LangChain索引API提供了一套简化的内容索引工作流程,帮助我们将来自任何来源的文档加载并保持与向量存储同步。索引API的主要优势在于:
- 避免重复写入已存在的内容
- 避免重写未变更的内容
- 避免对未变更的内容重新计算嵌入
这些功能可以节省时间和成本,并提高向量搜索结果的质量。本文将深入探讨LangChain索引的工作机制,包括如何利用文档经过多个转换步骤后进行索引。
核心原理解析
LangChain索引通过记录管理器(RecordManager)来跟踪文档写入向量存储的状态。每当进行内容索引时,会为每个文档计算哈希值,并将以下信息存储在记录管理器中:
- 文档哈希(包括页面内容和元数据的哈希)
- 写入时间
- 来源ID — 每个文档都需要在元数据中包含来源信息,以确定文档的最终来源
删除模式
在向量存储中索引文档时,可能需要删除某些现有文档。LangChain索引API提供了多种删除模式以满足不同需求:
- None: 不执行任何自动清理,仅进行内容去重。
- Incremental: 持续清理已变更的内容。
- Full: 在索引结束后清理所有未包含的文档。
代码实现演示
以下是一个基本的代码示例,演示如何使用LangChain索引API进行内容索引:
from langchain.indexes import SQLRecordManager, index
from langchain_core.documents import Document
from langchain_elasticsearch import ElasticsearchStore
from langchain_openai import OpenAIEmbeddings
# 初始化嵌入和向量存储
collection_name = "test_index"
embedding = OpenAIEmbeddings()
# 使用稳定可靠的Elasticsearch存储
vectorstore = ElasticsearchStore(
es_url="http://localhost:9200", index_name="test_index", embedding=embedding
)
# 初始化记录管理器
namespace = f"elasticsearch/{collection_name}"
record_manager = SQLRecordManager(
namespace, db_url="sqlite:///record_manager_cache.sql"
)
# 创建记录管理器模式
record_manager.create_schema()
# 索引一些测试文档
doc1 = Document(page_content="kitty", metadata={"source": "kitty.txt"})
doc2 = Document(page_content="doggy", metadata={"source": "doggy.txt"})
def _clear():
"""清空内容帮助函数"""
index([], record_manager, vectorstore, cleanup="full", source_id_key="source")
# 使用None删除模式进行索引
_clear()
index([doc1, doc2], record_manager, vectorstore, cleanup=None, source_id_key="source")
# 使用Incremental删除模式进行索引
_clear()
index([doc1, doc2], record_manager, vectorstore, cleanup="incremental", source_id_key="source")
# 使用Full删除模式进行索引
_clear()
all_docs = [doc1, doc2]
index(all_docs, record_manager, vectorstore, cleanup="full", source_id_key="source")
应用场景分析
LangChain索引API适用于需要频繁更新内容的场景,尤其是在多步文档转换后进行存储的时候。可以通过删除模式选择增量或全量清理,为不断变更的内容提供支持。
实践建议
- 选择合适的删除模式: 根据具体应用场景选择Incremental或Full模式,以确保文档的一致性。
- 优化性能: 确保记录管理器使用高分辨率时间戳以避免清理误差。
- 定义合理的命名空间: 使用命名空间结合存储类型和集合名,以确保不同应用间的数据隔离。
如果遇到问题欢迎在评论区交流。
—END—