langchain相似度检索
时间: 2024-01-03 09:21:24 浏览: 349
根据提供的引用内容,langchain的相似度比较默认是通过欧式距离,而embedding模型多是用余弦相似度比较。因此,如果要使用langchain进行相似度检索,需要更改相似度比较的方式为余弦相似度。
以下是使用FAISS库实现余弦相似度检索的示例代码:
```python
import numpy as np
import faiss
# 构造数据
d = 64 # 向量维度
nb = 100000 # 向量数量
xb = np.random.random((nb, d)).astype('float32')
# 建立索引
index = faiss.IndexFlatL2(d) # 使用欧式距离
index = faiss.IndexFlatIP(d) # 使用余弦相似度
index.add(xb)
# 查询
k = 5 # 返回的最近邻数量
xq = np.random.random((1, d)).astype('float32')
D, I = index.search(xq, k)
print(I) # 最近邻向量的索引
print(D) # 最近邻向量与查询向量的距离
```
相关问题
langchain库 检索
### LangChain 实现检索功能的方法
LangChain 是一种强大的工具,用于构建基于大型语言模型的应用程序。它提供了多种方式来实现检索功能,包括向量数据库集成、文本分割以及查询优化等功能。
#### 1. 向量存储与检索
通过 LangChain 的 `Chroma` 或其他支持的向量数据库(如 Pinecone 和 Weaviate),可以轻松实现高效的相似度搜索。以下是具体实现方法:
- **加载文档**
首先需要加载要处理的数据源。可以通过内置的 `WebBaseLoader` 加载网页内容或其他类型的文件[^4]。
```python
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://example.com")
docs = loader.load()
```
- **分词操作**
将原始文档拆分为较小的部分以便于嵌入和存储。推荐使用 `RecursiveCharacterTextSplitter` 进行递归字符分割。
```python
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
splits = text_splitter.split_documents(docs)
```
- **嵌入与存储**
利用 OpenAI 提供的嵌入服务将文本转换成高维向量,并将其存入 Chroma 数据库中。
```python
from langchain_openai import OpenAIEmbeddings
from langchain import hub
from langchain_chroma import Chroma
embedding = OpenAIEmbeddings()
db = Chroma.from_documents(splits, embedding)
retriever = db.as_retriever(search_kwargs={"k": 3})
```
#### 2. 查询优化策略
为了提高检索效率和准确性,可采用改写—检索—读取模式。此流程涉及三个主要阶段:预处理输入查询语句;执行实际查找过程;最后综合返回的结果形成最终答复[^2]。
- **安装必要组件**
```bash
pip install -U langchain-cli
```
- **创建项目结构**
定义清晰的工作流有助于更好地管理和扩展应用逻辑。例如,在初始化一个新的 LangChain 工程时可以选择合适的模板快速搭建框架。
#### 3. 父文档检索器
对于复杂场景下的多级关联关系分析,则需要用到更高级别的父文档检索机制。这种方法允许我们不仅关注单个节点本身的信息,还考虑到了它们之间的层次连接情况[^3]。
```python
parent_doc_retrieval_chain = ParentDocumentRetriever(
child_splitter=text_splitter,
parent_splitter=ParentSplitter(),
search=retriever
)
result = parent_doc_retrieval_chain.invoke(query="your query here")
print(result['source'])
```
以上展示了如何利用 LangChain 库完成基本到复杂的各种形式的内容检索任务。
langchain混合检索
### LangChain 混合检索概述
混合检索旨在结合不同类型的搜索算法优势,从而提供更高质量的结果。在LangChain框架内,这种组合通常涉及传统基于关键词的搜索引擎(如Elasticsearch)与现代向量相似度匹配机制之间的协作[^1]。
### 向量存储的选择
为了有效实施混合搜索,在构建系统之初就需要挑选合适的向量数据库作为支撑平台。理想的候选者应当具备高效处理大规模数据集的能力,并且能够无缝集成到现有的基础设施当中。例如,Astra DB就是一个不错的选择,它允许开发者通过简单的`body_search`参数配置来启用强大的混合查询功能[^2]。
### 实现步骤详解
#### 步骤一:初始化环境并加载必要库
首先确保安装了最新版本的Python以及所需的第三方依赖项:
```bash
pip install langchain elasticsearch astrapy
```
接着导入必要的模块:
```python
from langchain import LangChain, DenseRetriever
import elasticsearch
```
#### 步骤二:连接至目标索引
建立与Elasticsearch实例间的通信链路,并指定要操作的具体索引名称:
```python
es_client = elasticsearch.Elasticsearch("http://localhost:9200")
index_name = 'my_documents'
```
#### 步骤三:定义向量字段映射结构
针对待嵌入的内容创建相应的密集型表示形式——即所谓的"dense vector"[^3]:
```json
{
"mappings": {
"properties": {
"content_embedding": {"type": "dense_vector", "dims": 768}
}
}
}
```
此JSON片段描述了一个具有固定维度大小为768维的空间坐标系,用于容纳由预训练模型生成的文章摘要或其他文本特征编码结果。
#### 步骤四:编写自定义评分函数
当面对来自多个渠道的数据流时,合理分配权重变得尤为重要。这里介绍了一种称为“递减排名融合”的策略(RRF),其核心思想在于综合考虑各个子系统的相对重要程度,最终得出统一排序列表[^4]。
```python
def rrf_score(documents):
scores = []
for doc in documents:
score_sum = sum([1 / (rank + k) for rank in doc['ranks']])
scores.append((doc['_id'], score_sum))
return sorted(scores, key=lambda x: x[1], reverse=True)
# 参数k可以根据实际情况调整,默认取值为60
k = 60
```
上述代码实现了对输入文档集合按照RRF原则打分的过程,其中每个元素都包含了原始ID及其对应的累积得分;最后一步则是依据总分数高低完成降序排列。
### 结论
综上所述,借助于LangChain所提供的灵活接口设计思路,配合恰当的技术选型方案,完全可以打造出一套既满足业务需求又具有良好扩展性的混合检索引擎架构体系。值得注意的是,实际项目开发过程中还需充分考虑到诸如性能调优、异常捕获等诸多细节方面的工作。
阅读全文
相关推荐




