LangChain的RAG应用通过结合检索和生成两种方法,实现了文档和信息检索后的智能生成,适用于需要从大规模文档中快速获取信息并进行总结或回答的问题。以下是一个基于LangChain和自定义嵌入模型实现RAG应用的示例。
1. 自定义嵌入模型
首先定义了一个自定义的DoubaoEmbeddings类,继承自LangChain的Embeddings接口,并使用VolcEngine的Ark客户端调用API生成文本的嵌入。
class DoubaoEmbeddings(BaseModel, Embeddings):
client: Ark = None
api_key: str = ""
model: str
def __init__(self, **data: Any):
super().__init__(**data)
if self.api_key == "":
self.api_key = os.environ["OPENAI_API_KEY"]
self.client = Ark(base_url=os.environ["OPENAI_BASE_URL"], api_key=self.api_key)
def embed_query(self, text: str) -> List[float]:
embeddings = self.client.embeddings.create(model=self.model, input=text)
return embeddings.data[0].embedding
def embed_documents(self, texts: List[str]) -> List[List[float]]:
return [self.embed_query(text) for text in texts]
- embed_query: 为单一文本生成嵌入向量。
- embed_documents: 批量生成文本嵌入。
2. 使用缓存加速嵌入生成
为了避免重复计算嵌入,可以利用CacheBackedEmbeddings对嵌入进行缓存,将结果存储在InMemoryStore中。
from langchain.embeddings import CacheBackedEmbeddings
from langchain.storage import InMemoryStore
store = InMemoryStore()
embedder = CacheBackedEmbeddings.from_bytes_store(underlying_embeddings, store, namespace=underlying_embeddings.model)
CacheBackedEmbeddings确保相同文本的嵌入只计算一次,节省计算资源。
3. 构建索引
使用VectorstoreIndexCreator创建一个基于文档的向量索引。该索引能够支持快速检索相关信息。
from langchain.indexes import VectorstoreIndexCreator
index = VectorstoreIndexCreator(embedding=embeddings).from_loaders([loader])
该过程将文档加载器与嵌入模型结合,通过将文档向量化并存储,创建一个可搜索的索引。
4. 查询与生成回答
通过加载的索引和预训练的LLM模型,可以根据输入的查询自动从文档中检索相关内容并生成答案。
llm = ChatOpenAI(model=os.environ["LLM_MODELEND"], temperature=0)
query = "玫瑰花的花语是什么?"
result = index.query(llm=llm, question=query)
这段代码演示了如何通过用户输入的查询,使用生成模型(如ChatOpenAI)对检索到的文档进行上下文理解并生成回答。
5. 文本切割与存储
为了处理大规模文本,可以使用CharacterTextSplitter将长文本分割成更小的块,以便于索引和检索。
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
这种方法有助于提高检索效率,特别是在处理大量文本时。
总结
这个示例展示了如何利用LangChain的RAG框架,通过嵌入模型、文档加载器、向量索引和生成模型,创建一个智能问答系统。通过缓存优化、文本切割和索引构建等技巧,可以有效提高系统的性能和响应速度。