
Introducing Agent-based RAG
基于代理的 RAG 介绍
An implementation with LangGraph, Azure AI Search and Azure OpenAI GPT-4o
使用 LangGraph、Azure AI Search 和 Azure OpenAI GPT-4o 进行实施
Among the various architectural patterns in the field of Generative AI, Retrieval Augmented Generation (RAG) was the first and probably still most polular to be around.
在生成式人工智能领域的各种架构模式中,检索增强生成(RAG)是最早出现的,可能也是目前最流行的。
RAG is a technique that allows the generative models to access external knowledge sources, such as documents, databases, or web pages, and use them as additional inputs for generating responses. By doing so, RAG can improve the quality, diversity, and reliability of the generated content, as well as provide transparency and verifiability for the users.
RAG 是一种允许生成模型访问外部知识源(如文档、数据库或网页)并将其用作生成响应的额外输入的技术。通过这样做,RAG 可以提高生成内容的质量、多样性和可靠性,并为用户提供透明度和可验证性。
Over the last months, many variations of RAG have been developed (GraphRAG, Adaptive RAG, Corrective RAG…), with the goal of improving some weaknesses of the “traditional” RAG pipeline.
在过去的几个月里,人们开发了许多 RAG 变体(GraphRAG、Adaptive RAG、Corrective RAG......),目的是改进 "传统 "RAG 管道的一些弱点。
In this article, we are going to see one of these variations: Agentic RAG. Before diving into the topic, let’s refresh how the two main ingredients of this solution — RAG and Agents — are defined.
本文将介绍其中一种变体:代理 RAG。在深入探讨这个主题之前,让我们先复习一下这个解决方案的两个主要成分--RAG 和代理--是如何定义的。
What is RAG?
什么是 RAG?
Retrieval Augmented Generation (RAG) is a powerful technique in LLM-powered applications scenarios that addresses the following problem: “what if I want to ask my LLM something that is not part of the training set where the LLM was trained?”. The idea behind RAG is that of decoupling the LLM from the knowledge base we want to navigate through, which is properly vectorized or embedded and stored into a VectorDB.
检索增强生成(RAG)是 LLM 驱动的应用场景中的一项强大技术,它可以解决以下问题:"如果我想向我的 LLM 询问一些不属于 LLM 训练集的内容怎么办?RAG 背后的理念是将 LLM 与我们要浏览的知识库解耦,知识库被适当地矢量化或嵌入并存储到 VectorDB 中。
RAG is made of three phases:
RAG 由三个阶段组成:
- Retrieval → given a user’s query and its corresponding vector, the most similar pieces of documents (those corresponding to the vectors that are closer to the user query’s vector) are retrieved and used as the base context for the LLM.
检索 → 给定用户查询及其对应的向量,检索出最相似的文档(与用户查询向量较为接近的向量对应的文档),并将其作为 LLM 的基础上下文。

- Augmentation →the retrieved context is enriched through additional instructions, rules, safety guardrails and similar practices that are typical of prompt engineering techniques.
扩充→通过额外的指令、规则、安全警戒线和类似的做法来丰富检索到的上下文,这些都是典型的提示性工程技术。

- Generation →based on the augmented context, the LLM generates the response to the user’s query.
生成→根据增强的上下文,LLM 生成对用户查询的回复。

As mentioned, a typical RAG application assumes an underlying VectorDB where all the embedded knowledge base is stored.
如前所述,典型的 RAG 应用程序假定有一个底层 VectorDB,所有嵌入式知识库都存储在这里。
What is an Agent?
什么是代理人?
Over the last months, many LLMs-powered applications converged into the framework of AI Agents, that can be defined as specialized entities designed to address user’s query and perform tasks. More specifically, an AI Agent present the following features:
在过去的几个月里,许多由 LLMs 驱动的应用都汇聚到了人工智能代理的框架中,人工智能代理可以被定义为专门用于处理用户查询和执行任务的实体。更具体地说,人工智能代理具有以下特征:
- It is powered by an LLM (or SML) which act as “brain” of the application. This means that Agents are capable of planning a sequence of action to accomplish user’s query.
它由作为应用程序 "大脑 "的 LLM(或 SML)驱动。这意味着,代理能够规划一连串的操作,以完成用户的查询。 - It has access to a set of tools or plug-ins to execute actions in the surrounding ecosystem (e.g. querying data in an ERP, sending an email with a generated newsletter, posting a picture on Linkedin…)
它可以访问一系列工具或插件,以便在周边生态系统中执行操作(例如,在企业资源规划系统中查询数据、发送带有生成的时事通讯的电子邮件、在 Linkedin 上发布图片......)。 - With the advent of multimodality, an AI Agent can now perceive the surrounding environment in all its elements. For example, an AI agent could see a car damage due to an accident, say it loud to the car owner and send a claim to the insurance company.
随着多模态技术的出现,人工智能代理现在可以感知周围环境的所有元素。例如,人工智能代理可以看到因事故造成的汽车损坏,大声告诉车主并向保险公司提出索赔。 - It has the ability to remember its past interactions and behaviors, which are also leveraged for future improvement. This component is called memory (more specifically, short-term memory).
它有能力记住自己过去的互动和行为,这也是未来改进的杠杆。这个部分被称为记忆(更具体地说,是短期记忆)。
Combining Agents and RAG to obtain Agentic RAG
将代理和 RAG 结合起来,获得代理 RAG
When we introduce the concept of agents into a RAG pipeline, we are adding a layer of intelligence between user’s query and model’s retrieval. This leads to a series of benefits:
当我们在 RAG 管道中引入代理的概念时,我们就在用户查询和模型检索之间增加了一层智能。这将带来一系列好处:
- We can instructs the agent to follow a specific thought process, even prompting it to re-think its work
我们可以指示代理遵循特定的思维过程,甚至促使它重新思考自己的工作 - We can specialize multiple agents for multiple tasks, such as summarization, as well as for specific clusters of documents.
我们可以为多种任务(如摘要)以及特定的文件群专门设计多个代理。
In this article, we are going to see a simple implementation based on this notebook.
在本文中,我们将看到基于该笔记本的简单实现。
Scenario: Imagine we own a climbing equipments’ company and we want to upgrade our website with an AI powered chatbot. This latter aims at recommending climbing gears to users. Plus, we also partner with a travel agency tha organizes trekking in Nepals, so we want my chatbot to be able to suggest trekkings upon user’s request. Finally, we have a database containing past customers’ interactions, and we want my chabot to be able to retrieve this information so that it can better address user’s request.
情景:假设我们拥有一家攀岩装备公司,我们想用人工智能聊天机器人升级我们的网站。后者旨在向用户推荐登山装备。此外,我们还与一家组织尼泊尔徒步旅行的旅行社合作,因此我们希望聊天机器人能够根据用户的要求推荐徒步旅行。最后,我们有一个包含过去客户互动的数据库,我们希望聊天机器人能够检索这些信息,以便更好地满足用户的要求。
We are going to need the following components:
我们需要以下组件:
- An Agent that process user’s query and decide which tools to use
处理用户查询并决定使用哪些工具的代理 - A RAG pipeline that is specialized on climbing products descriptions
专门描述攀岩产品的 RAG 管道 - A RAG pipeline that is specialized on trekking packages descriptions
专门提供徒步旅行套餐说明的 RAG 管道 - A SQL toolkit that can query databases and lookup user’s name with its previous interactions.
一个 SQL 工具包,可查询数据库,并通过用户名与之前的交互进行查找。
To do so, we will leverage LangGraph, a LangChain’s library introduced in January 2024 and meant to easily manage multi-agents application with a graph-based approach (you can learn more about LangGraph in my previous article).
为此,我们将利用 LangGraph,它是 LangChain 于 2024 年 1 月推出的一个库,旨在通过基于图形的方法轻松管理多代理应用程序(您可以在我之前的文章中了解更多有关 LangGraph 的信息)。
Let’s get started!
让我们开始吧!
Technical demonstration
技术演示
Let’s start by initializing our models. For this purpose, we will need a chat model (I’ll use Azure OpenAI GPT-4o) and an embedding model (I’ll use the text-embedding-3-large model).
让我们从初始化模型开始。为此,我们需要一个聊天模型(我将使用 Azure OpenAI GPT-4o)和一个嵌入模型(我将使用 text-embedding-3-large 模型)。
import os
from langchain_openai import AzureOpenAI
os.environ["AZURE_OPENAI_API_VERSION"] = "2024-02-15-preview"
os.environ["AZURE_OPENAI_ENDPOINT"] = "xxx"
os.environ["AZURE_OPENAI_API_KEY"] = "xxx"
os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"] = "gpt-4o"
from langchain_core.messages import HumanMessage
from langchain_openai import AzureChatOpenAI
model = AzureChatOpenAI(
openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],
azure_deployment=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"],
)
from langchain_openai import AzureOpenAIEmbeddings
embeddings = AzureOpenAIEmbeddings(
azure_deployment="text-embedding-3-large"
)Then, we need to initialize our tools.
然后,我们需要初始化我们的工具。
SQL DB tool
SQL DB 工具
For the SQL DB tool, I first initialized a sample DB leveraging the python library sqlite3 (you can easily install it via pip install sqlite3).
对于 SQL DB 工具,我首先利用 python 库 sqlite3 初始化了一个示例 DB(可以通过 pip install sqlite3 轻松安装)。
import sqlite3
import pandas as pd
# Sample data from the CSV
data = {
"Name": ["John Doe", "Jane Smith", "Alex Johnson", "Chris Lee", "Patricia Brown"],
"Gender": ["Male", "Female", "Male", "Non-binary", "Female"],
"Age": [28, 34, 22, 29, 41],
"Previous Purchases": [
"Pro Gear 123 Climbing Shoes, UltraClip Carabiner, StrongRope 500",
"ClimbSafe Harness, GripMaster Chalk Bag, RockShield Helmet",
"QuickClip Carabiner",
"SummitX Climbing Shoes, ClimbSafe Harness",
"StrongRope 500, ProGrip Chalk, SecureBelay Device, QuickLink Quickdraw Set"
],
"Reviews Given": [
"I really liked this product!",
"The product quality is great, highly recommend!",
"It's okay, but I expected better.",
"Good value for the price.",
"Excellent gear, will buy again!"
]
}
# Converting the dictionary to a DataFrame
df = pd.DataFrame(data)
# Connecting to a SQLite database (it will create a new one if it doesn't exist)
conn = sqlite3.connect('climbing_gear_customers.db')
# Storing the DataFrame in the SQLite database
df.to_sql('customer_interactions', conn, index=False, if_exists='replace')
# Committing and closing the connection
conn.commit()
conn.close()To initialize the tool, we will leverage the pre-built LangChain library:
为了初始化该工具,我们将利用预置的 LangChain 库:
from langchain_community.agent_toolkits.sql.toolkit import SQLDatabaseToolkit
toolkit = SQLDatabaseToolkit(db=db, llm=model)
toolkit.get_tools()[QuerySQLDataBaseTool(description="Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.", db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x000002149106FF10>),
InfoSQLDatabaseTool(description='Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3', db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x000002149106FF10>),
ListSQLDatabaseTool(db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x000002149106FF10>),
QuerySQLCheckerTool(description='Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query!', db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x000002149106FF10>, llm=AzureChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x000002148E435C90>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x000002148E840050>, openai_api_key=SecretStr('**********'), openai_proxy='', azure_endpoint='https://aoao-sweden.openai.azure.com/', deployment_name='gpt-4o', openai_api_version='2024-02-15-preview', openai_api_type='azure'), llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['dialect', 'query'], template='\n{query}\nDouble check the {dialect} query above for common mistakes, including:\n- Using NOT IN with NULL values\n- Using UNION when UNION ALL should have been used\n- Using BETWEEN for exclusive ranges\n- Data type mismatch in predicates\n- Properly quoting identifiers\n- Using the correct number of arguments for functions\n- Casting to the correct data type\n- Using the proper columns for joins\n\nIf there are any of the above mistakes, rewrite the query. If there are no mistakes, just reproduce the original query.\n\nOutput the final SQL query only.\n\nSQL Query: '), llm=AzureChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x000002148E435C90>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x000002148E840050>, openai_api_key=SecretStr('**********'), openai_proxy='', azure_endpoint='https://aoao-sweden.openai.azure.com/', deployment_name='gpt-4o', openai_api_version='2024-02-15-preview', openai_api_type='azure')))]As you can see, the SQLDatabaseToolkit comes with 4 pre-built tools that help the model to work with tables in a database.
如您所见,SQLDatabaseToolkit 附带了 4 个预建工具,可帮助模型处理数据库中的表。
Climbing products sheets
攀岩产品表
The first cluster of documents will be the climbing products sheet (you can find it in the github repo). To store our embeddings, I’ll leverage the Azure AI Search vector store (to create one instance on your Azure subscription, you can see the tutorial here).
第一个文档集群将是攀登产品表(可在 github repo 中找到)。为了存储我们的嵌入,我将利用 Azure AI Search 向量存储(在您的 Azure 订阅中创建一个实例,请参阅此处的教程)。
Let’s first initialize our vector store secrets leveraging LangChain built-in library:
首先,让我们利用 LangChain 内置库初始化我们的向量存储秘密:
from langchain_community.vectorstores.azuresearch import AzureSearch
vector_store_address: str = "xxx"
vector_store_password: str = "xxx"
index_name: str = "climbing-products-demo"
vector_store: AzureSearch = AzureSearch(
azure_search_endpoint=vector_store_address,
azure_search_key=vector_store_password,
index_name=index_name,
embedding_function=embeddings.embed_query,
)Then, we can upload the document:
然后,我们就可以上传文件了:
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
file_path = (
"Climbing product sheet.pdf"
)
loader = PyPDFLoader(file_path)
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
vector_store.add_documents(documents=docs)Finally, we can convert our vector store to a retriever that will be used to create the first RAG pipeline tool:
最后,我们可以将矢量存储转换为检索器,用来创建第一个 RAG 管道工具:
from langchain_community.retrievers import AzureAISearchRetriever
products_retriever = AzureAISearchRetriever(
content_key="content", top_k=1, index_name="climbing-products-demo", service_name="aisearchvaalt", api_key = "xxx"
)
from langchain.tools.retriever import create_retriever_tool
climbing_products_tool = create_retriever_tool(
products_retriever,
"climbing_products_search",
"""
Search and return information about climbing products.
"""
)Trekking descriptions
徒步旅行说明
We can follow the same reasoning for the trekking documents (I took some descriptions from the OutfitterNepal website). The only difference is that here, since we have multiple PDFs, we are going to leverage the PyPDFDirectoryLoader library.
我们可以用同样的方法来处理徒步旅行文档(我从 OutfitterNepal 网站上获取了一些描述)。唯一不同的是,在这里,由于我们有多个 PDF 文件,我们将利用 PyPDFDirectoryLoader 库。
from langchain.document_loaders import PyPDFDirectoryLoader
index_name: str = "trekking-demo"
vector_store: AzureSearch = AzureSearch(
azure_search_endpoint=vector_store_address,
azure_search_key=vector_store_password,
index_name=index_name,
embedding_function=embeddings.embed_query,
)
file_path = (
"trekking"
)
loader = PyPDFDirectoryLoader(file_path)
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
vector_store.add_documents(documents=docs)
trekking_retriever = AzureAISearchRetriever(
content_key="content", top_k=1, index_name="trekking-demo", service_name="aisearchvaalt", api_key = "xxx"
)
from langchain.tools.retriever import create_retriever_tool
trekking_tool = create_retriever_tool(
trekking_retriever,
"trekking_search",
"""
Search and return information about trekkings in Nepal.
"""
)Now that we have all the tools, we can save them into a list that will be needed in the following section:
现在我们已经掌握了所有工具,可以将它们保存到一个列表中,以便在下一节中使用:
tools = [climbing_products_tool, trekking_tool, toolkit.get_tools()[0], toolkit.get_tools()[1], toolkit.get_tools()[2], toolkit.get_tools()[3]]Building the graph
绘制图表
Now we have all the ingredients to start building our graph. Let’s initialize the Agent states and some utils functions that I took from this notebook:
现在,我们已经具备了开始构建图形的所有要素。让我们初始化代理状态和我从这本笔记本中摘录的一些实用工具函数:
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import AnyMessage, add_messages
class State(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
from langchain_core.messages import ToolMessage
from langchain_core.runnables import RunnableLambda
from langgraph.prebuilt import ToolNode
def handle_tool_error(state) -> dict:
error = state.get("error")
tool_calls = state["messages"][-1].tool_calls
return {
"messages": [
ToolMessage(
content=f"Error: {repr(error)}\n please fix your mistakes.",
tool_call_id=tc["id"],
)
for tc in tool_calls
]
}
def create_tool_node_with_fallback(tools: list) -> dict:
return ToolNode(tools).with_fallbacks(
[RunnableLambda(handle_tool_error)], exception_key="error"
)
def _print_event(event: dict, _printed: set, max_length=1500):
current_state = event.get("dialog_state")
if current_state:
print("Currently in: ", current_state[-1])
message = event.get("messages")
if message:
if isinstance(message, list):
message = message[-1]
if message.id not in _printed:
msg_repr = message.pretty_repr(html=True)
if len(msg_repr) > max_length:
msg_repr = msg_repr[:max_length] + " ... (truncated)"
print(msg_repr)
_printed.add(message.id)Then we can initialize our Assistant class. Here I’ll set a state that will be read by nodes which is the customer’s name (it will be needed to lookup with the db). Plus, I’m setting the prompt with the assistant’s instructions, specifying to always retrieve user’s information from the db:
然后,我们就可以初始化助手类了。在这里,我将设置一个由节点读取的状态,即客户姓名(在数据库中查询时需要)。此外,我还将根据助手的指令设置提示,指定始终从数据库中检索用户信息:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import Runnable, RunnableConfig
import datetime
class Assistant:
def __init__(self, runnable: Runnable):
self.runnable = runnable
def __call__(self, state: State, config: RunnableConfig):
while True:
configuration = config.get("configurable", {})
name = configuration.get("name", None)
state = {**state, "user_info": name}
result = self.runnable.invoke(state)
# If the LLM happens to return an empty response, we will re-prompt it
# for an actual response.
if not result.tool_calls and (
not result.content
or isinstance(result.content, list)
and not result.content[0].get("text")
):
messages = state["messages"] + [("user", "Respond with a real output.")]
state = {**state, "messages": messages}
else:
break
return {"messages": result}
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"You are a helpful customer support for a climbing company. "
"given customer's name, make sure to first query the db and then incorporate customer's information from the database. "
" Use the provided tools to search for climbing gears and trekkings in Nepal, upon customer's request. "
"\n\nCurrent user:\n<User>\n{user_info}\n</User>"
),
("placeholder", "{messages}"),
]
)
assistant_runnable = prompt | model.bind_tools(tools)Lastly, let’s define the structure of the graph:
最后,我们来定义图形的结构:
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import END, StateGraph, START
from langgraph.prebuilt import tools_condition
builder = StateGraph(State)
# Define nodes: these do the work
builder.add_node("assistant", Assistant(assistant_runnable))
builder.add_node("tools", create_tool_node_with_fallback(tools))
# Define edges: these determine how the control flow moves
builder.add_edge(START, "assistant")
builder.add_conditional_edges(
"assistant",
tools_condition,
)
builder.add_edge("tools", "assistant")
# The checkpointer lets the graph persist its state
# this is a complete memory for the entire graph.
memory = MemorySaver()
part_1_graph = builder.compile(checkpointer=memory)You can print the diagram to see how it looks like:
您可以打印该图,看看它是什么样子的:
from IPython.display import Image, display
try:
display(Image(part_1_graph.get_graph(xray=True).draw_mermaid_png()))
except Exception:
pass
Now it’s time to test it. I’ll loop over 2 questions, configuring “John Doe” as customer’s name as follows:
现在是测试的时候了。我将循环回答 2 个问题,将 "John Doe "配置为客户姓名,如下所示:
import shutil
import uuid
# Let's create an example conversation a user might have with the assistant
tutorial_questions = [
"Hi there, Can you help me find some climbing shoes based on my previous purchases?",
"I want to do a trekking on the highest base camp in nepal, which trek would you recommend?",
]
thread_id = str(uuid.uuid4())
config = {
"configurable": {
# The passenger_id is used in our flight tools to
# fetch the user's flight information
"name": "John Doe",
# Checkpoints are accessed by thread_id
"thread_id": thread_id,
}
}
_printed = set()
for question in tutorial_questions:
events = part_1_graph.stream(
{"messages": ("user", question)}, config, stream_mode="values"
)
for event in events:
_print_event(event, _printed)================================[1m Human Message [0m=================================
Hi there, Can you help me find some climbing shoes based on my previous purchases?
==================================[1m Ai Message [0m==================================
Tool Calls:
sql_db_list_tables (call_VmBjy2UMir0XCzuLRSHarmIP)
Call ID: call_VmBjy2UMir0XCzuLRSHarmIP
Args:
=================================[1m Tool Message [0m=================================
Name: sql_db_list_tables
customer_interactions
==================================[1m Ai Message [0m==================================
Tool Calls:
sql_db_schema (call_GtEVD8CeziJjPu8zYU9XN3zO)
Call ID: call_GtEVD8CeziJjPu8zYU9XN3zO
Args:
table_names: customer_interactions
=================================[1m Tool Message [0m=================================
Name: sql_db_schema
CREATE TABLE customer_interactions (
"Name" TEXT,
"Gender" TEXT,
"Age" INTEGER,
"Previous Purchases" TEXT,
"Reviews Given" TEXT
)
/*
3 rows from customer_interactions table:
Name Gender Age Previous Purchases Reviews Given
John Doe Male 28 Pro Gear 123 Climbing Shoes, UltraClip Carabiner, StrongRope 500 I really liked this product!
Jane Smith Female 34 ClimbSafe Harness, GripMaster Chalk Bag, RockShield Helmet The product quality is great, highly recommend!
Alex Johnson Male 22 QuickClip Carabiner It's okay, but I expected better.
*/
==================================[1m Ai Message [0m==================================
Tool Calls:
sql_db_query (call_gjaIbln4CbmrqTDAukv7raVX)
Call ID: call_gjaIbln4CbmrqTDAukv7raVX
Args:
query: SELECT "Previous Purchases" FROM customer_interactions WHERE Name = 'John Doe'
=================================[1m Tool Message [0m=================================
Name: sql_db_query
[('Pro Gear 123 Climbing Shoes, UltraClip Carabiner, StrongRope 500',)]
==================================[1m Ai Message [0m==================================
Tool Calls:
climbing_products_search (call_afcXKmEHESg2eyMxVxQ9VwXA)
Call ID: call_afcXKmEHESg2eyMxVxQ9VwXA
Args:
query: climbing shoes
=================================[1m Tool Message [0m=================================
Name: climbing_products_search
absorbs impacts, ensuring your safety in case of falls or rockfalls. The helmet has an
adjustable fit system, ventilation holes, and a headlamp attachment for climbing in low -
light conditions.
• Specifications:
o Material: ABS shell, EPS foam liner
o Weight: 280 grams
o Ventilation: 10 air vents
o Fit System: Adjustable dial
o Headlamp Attachment: Yes
o Sizes: S/M, M/L
o Colors: White, Orange, Blue
7. QuickClip Carabiner
• Category: Hardware
• Description: The QuickClip Carabiner is a compact and lightweight carabiner designed
for quickdraws and other climbing applications. Its compact size and smooth gate
action make it easy to clip and unclip during climbs. It is constructed from high -strength
aluminum, ma king it both lightweight and durable.
• Specifications:
o Material: Aluminum
o Weight: 40 grams
o Gate Opening: 20mm
o Strength: 22 kN (major axis), 7 kN (minor axis), 6 kN (open gate)
o Colors: Red, Blue, Green
8. SummitX Climbing Shoes
• Category: Footwear
• Description: The SummitX Climbing Shoes are built for technical climbs where
precision and performance are key. These shoes feature an aggressive downturn, sticky
rubber soles, and a tight fit to ensure maximum control on small holds. The leather
upper stretches over time for a custom fit, making these shoes ideal for advanced
climbers. ... (truncated)
==================================[1m Ai Message [0m==================================
Hi John,
Based on your previous purchases, I see that you have bought the "Pro Gear 123 Climbing Shoes" before. Here are some other climbing shoes that you might be interested in:
### SummitX Climbing Shoes
- **Category:** Footwear
- **Description:** The SummitX Climbing Shoes are built for technical climbs where precision and performance are key. These shoes feature an aggressive downturn, sticky rubber soles, and a tight fit to ensure maximum control on small holds. The leather upper stretches over time for a custom fit, making these shoes ideal for advanced climbers.
- **Specifications:**
- **Material:** Leather upper, sticky rubber sole
- **Weight:** 450 grams per shoe
- **Closure Type:** Lace-up
Would you like more information on these shoes or any other climbing gear?
================================[1m Human Message [0m=================================
I want to do a trekking on the highest base camp in nepal, which trek would you recommend?
==================================[1m Ai Message [0m==================================
Tool Calls:
trekking_search (call_z2R0HmULjAjJ0S9JUdIrhoCP)
Call ID: call_z2R0HmULjAjJ0S9JUdIrhoCP
Args:
query: highest base camp in Nepal
=================================[1m Tool Message [0m=================================
Name: trekking_search
==================================[1m Ai Message [0m==================================
The highest base camp trek in Nepal is the **Everest Base Camp Trek**. Here are some details:
### Everest Base Camp Trek
- **Overview:** The Everest Base Camp (EBC) trek is one of the most iconic and challenging treks in the world. It takes you to the base of the world's highest peak, Mount Everest, standing at 8,848 meters. This trek offers breathtaking views of the Himalayas, including several of the world's highest peaks.
- **Duration:** Typically 12-16 days, depending on the itinerary.
- **Difficulty Level:** Strenuous. Suitable for fit and experienced trekkers.
- **Best Time to Trek:** Pre-monsoon (March to May) and post-monsoon (September to November).
- **Highlights:**
- Stunning views of Mount Everest, Lhotse, Nuptse, and Ama Dablam.
- Trekking through Sagarmatha National Park, a UNESCO World Heritage site.
- Visiting the famous Tengboche Monastery.
- Experiencing the unique Sherpa culture and hospitality.
- Reaching the Everest Base Camp at 5,364 meters.
Would you like more detailed information or assistance in planning your trek to Everest Base Camp?As you can see, the Agent was able to invoke the following tools:
如您所见,代理可以调用以下工具:
- sql_db_list_tables, sql_db_schema, and sql_db_query to understand the structure of the DB and extract the relevant information about John Doe
sql_db_list_tables、sql_db_schema 和 sql_db_query,以了解数据库结构并提取无名氏的相关信息 - climbing_products_search to retrieve information from the climbing products sheet
climbing_products_search 用于从攀岩产品表中检索信息 - trekking_search to retrieve information from the trekking directory
trekking_search 从徒步旅行目录中检索信息
Conclusions
结论
Agentic RAG is proving itself as a great technique to improve the quality of traditional RAG. Plus, in a landscape where AI Agents are rapidly evolving, having the flexibility of setting different RAG pipeline with different documents, system messages and tools is key to get to relevant results.
事实证明,Agentic RAG 是提高传统 RAG 质量的绝佳技术。此外,在人工智能代理迅速发展的今天,灵活地使用不同的文件、系统信息和工具设置不同的 RAG 管道,是获得相关结果的关键。
I’m curious to see whether there will be specific domains where this technique will shine more prominently.
我很想知道,这种技术是否会在某些特定领域大放异彩。
Code Repo →GenAI-Demos/Agentic RAG at main · Valentina-Alto/GenAI-Demos (github.com)
代码 Repo →GenAI-Demos/Agentic RAG at main - Valentina-Alto/GenAI-Demos (github.com)
References
参考资料
- Agentic RAG: What it is, its types, applications and implementation (leewayhertz.com)
代理 RAG:它是什么、它的类型、应用和实施(leewayhertz.com) - Create a search service in the portal — Azure AI Search | Microsoft Learn
在门户中创建搜索服务 - Azure AI Search | Microsoft Learn - Corrective RAG (CRAG) using local LLMs (langchain-ai.github.io)
使用本地 LLM 的纠正 RAG (CRAG) (langchain-ai.github.io) - Adaptive RAG (langchain-ai.github.io)
自适应 RAG(langchain-ai.github.io) - Agentic RAG (langchain-ai.github.io)
代理 RAG(langchain-ai.github.io) - 🦜🕸️LangGraph (langchain-ai.github.io)
🦜🕸️LangGraph (langchain-ai.github.io)





