微信扫码
添加专属顾问
我要投稿
今天探讨的便是RAG开发关于全文搜索,以及将全文检索和向量检索整合在一起的混合搜索(Hybrid Search)。
pip install llama-index-retrievers-bm25
为了便于在DuckDB里重现全文索引,这里使用DuckDB来存储
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader,Settings
from llama_index.llms.ollama import Ollama
from llama_index.core.node_parser import SentenceSplitter
from llama_index.retrievers.bm25 import BM25Retriever
# 这里仍然使用Ollama,你可以根据自己的情况,选择合适的LLM和embedding model
Settings.llm = Ollama(model="wizardlm2:7b-q5_K_M", request_timeout=300.0)
from llama_index.embeddings.ollama import OllamaEmbedding
Settings.embed_model = OllamaEmbedding(model_name="snowflake-arctic-embed:latest")
embed_dim=len(Settings.embed_model.get_query_embedding('hello'))
# 索引
documents = SimpleDirectoryReader("./data/paul_graham").load_data()
splitter = SentenceSplitter(chunk_size=1024) # 为了bm25需要,可以适当改小该值
nodes = splitter.get_nodes_from_documents(documents)
vector_store = DuckDBVectorStore(embed_dim=embed_dim,
database_name="paul.duck",
persist_dir="duckdb")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
storage_context.docstore.add_documents(nodes)
# vector retriever
vector_retriever = index.as_retriever(similarity_top_k=5)
# BM25Retriever
bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=5)
query = "What happened at Viaweb and Interleaf?"
from llama_index.core.response.notebook_utils import display_source_node
# will retrieve context from specific companies
nodes_bm25 = bm25_retriever.retrieve(query)
for node in nodes_bm25:
display_source_node(node)
import duckdb
conn = duckdb.connect('duckdb/paul.duck')
conn.sql('select * from documents limit 5').df()
conn.sql('install fts') # 第一次需要安装全文索引插件
conn.sql('load fts') # 加载全文索引插件
# 创建全文索引
conn.sql("PRAGMA create_fts_index('documents', 'node_id', 'text');")
# 重现 bm25_retriever.retrieve(query)
conn.sql(f"""
SELECT
fts_main_documents.match_bm25(node_id, '{query}') AS score,
node_id, text
FROM documents
WHERE score IS NOT NULL
ORDER BY score DESC
LIMIT 5
""").df()
对比bm25_retriever.retrieve(query)的实现, 结果略有不同, 因为使用的bm25引擎不同, bm25_retriever 使用的是 rank_bm25[1]
关于DuckDB 全文索引插件的使用,详见,https://duckdb.org/docs/extensions/full_text_search
接下来重现全文检索与向量检索选哪个? 提到的混合搜索
relativeScoreFusion 通过分别归一化向量搜索和关键词搜索输出的指标来确定每个对象的得分。最高值设为1,最低值设为0,其他值根据这个尺度介于两者之间。因此,总得分是通过归一化的向量相似度和归一化的BM25得分的加权和来计算的。
from llama_index.core.retrievers import QueryFusionRetriever
retriever_relative_score = QueryFusionRetriever(
[vector_retriever, bm25_retriever],
retriever_weights=[0.6, 0.4],
similarity_top_k=10,
num_queries=1, # set this to 1 to disable query generation
mode="relative_score",
use_async=True,
verbose=True,
)
nodes_with_scores = retriever.retrieve(
"What happened at Interleafe and Viaweb?"
)
for node in nodes_with_scores:
print(f"Score: {node.score:.2f} - {node.text[:100]}...\n-----")
from llama_index.core.query_engine import RetrieverQueryEngine
query_engine = RetrieverQueryEngine.from_args(retriever_relative_score)
response = query_engine.query("What happened at Interleafe and Viaweb?")
display_response(response)
相对得分融合(Relative Score Fusion)的一个变体,基于分布的得分融合(Distribution-Based Score Fusion)以稍微不同的方式对得分进行缩放——基于每个结果集的得分的平均值和标准差。
from llama_index.core.retrievers import QueryFusionRetriever
retriever = QueryFusionRetriever(
[vector_retriever, bm25_retriever],
retriever_weights=[0.6, 0.4],
similarity_top_k=10,
num_queries=1, # set this to 1 to disable query generation
mode="dist_based_score",
use_async=True,
verbose=True,
)
nodes_with_scores = retriever.retrieve(
"What happened at Interleafe and Viaweb?"
)
for node in nodes_with_scores:
print(f"Score: {node.score:.2f} - {node.text[:100]}...\n-----")
from llama_index.core.query_engine import RetrieverQueryEngine
query_engine = RetrieverQueryEngine.from_args(retriever_relative_score)
response = query_engine.query("What happened at Interleafe and Viaweb?")
display_response(response)
到现在,我们不仅仅可以进行向量搜索,可以进行全文搜索,还可以使用两种方法进行混合搜索了。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-03-10
QwQ-32B,支持Function Call的推理模型,深度思考Agent的时代来了!
2025-03-10
国产自强!实在Agent+DeepSeek+华为昇腾一体机重磅发布!
2025-03-10
1次搭建完胜1亿次编码,MCP硅谷疯传!Anthropic协议解锁智能体「万能手」
2025-03-10
AI代理技术发展趋势与挑战
2025-03-10
有关智能体/Agent,和上下文协议/MCP的一些概念,以及为什么它重要
2025-03-10
通俗讲解DeepSeek中的GRPO:强化学习里的神奇算法
2025-03-10
AI智能体新秀 Manus失手泄底牌:Claude Sonnet沙盒代码大曝光!
2025-03-10
告别Agentic工作流?推理模型+行动链学习=Agent模型
2024-08-13
2024-06-13
2024-09-23
2024-08-21
2024-05-28
2024-07-31
2024-08-04
2024-04-26
2024-07-09
2024-09-17
2025-03-10
2025-03-10
2025-03-08
2025-03-08
2025-03-07
2025-03-07
2025-03-05
2025-03-05