langchain 链式写法-使用本地 embedding 模型,Faiss 检索

目录

示例代码1

示例代码2


示例代码1

使用本地下载的 embedding 模型去做 embedding,然后从中查相似的

python 复制代码
import os
from dotenv import load_dotenv
from langchain_community.llms import Tongyi
load_dotenv('key.env')  # 指定加载 env 文件
key = os.getenv('DASHSCOPE_API_KEY')  # 获得指定环境变量
DASHSCOPE_API_KEY = os.environ["DASHSCOPE_API_KEY"]  # 获得指定环境变量
model = Tongyi(temperature=1)


from langchain_core.prompts import ChatPromptTemplate, PromptTemplate, format_document
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_community.vectorstores.faiss import FAISS
from langchain_community.document_loaders import ArxivLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings

# 加载 arXiv 上的论文《ReAct: Synergizing Reasoning and Acting in Language Models》
loader = ArxivLoader(query="2210.03629", load_max_docs=1)
docs = loader.load()

# 把文本分割成 200 字一组的切片
text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
chunks = text_splitter.split_documents(docs)

embedding = HuggingFaceEmbeddings(model_name='bge-small-zh-v1.5')

# 构建 FAISS 向量存储和对应的 retriever
vs = FAISS.from_documents(chunks[:10], embedding)
# vs.similarity_search("What is ReAct")
retriever = vs.as_retriever()

# 构建 Document 转文本段落的工具函数
DEFAULT_DOCUMENT_PROMPT = PromptTemplate.from_template(template="{page_content}")
def _combine_documents(
    docs, document_prompt=DEFAULT_DOCUMENT_PROMPT, document_separator="\n\n"
):
    doc_strings = [format_document(doc, document_prompt) for doc in docs]
    return document_separator.join(doc_strings)

# 准备 Model I/O 三元组
template = """Answer the question based only on the following context:
{context}

Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)

# 构建 RAG 链
chain = (
    {
        "context": retriever | _combine_documents,
        "question": RunnablePassthrough()  # 直接作为 question 的值,不做任何操作
    }
    | prompt
    | model
    | StrOutputParser()
)
print(chain.invoke("什么是 ReAct?"))

示例代码2

txt 有多行,我的这份数据有 67 行,样例如下:

字段1\t值1\n

字段2\t值2\n

...

从中先检索最相似的,在传给大模型去选择,减少一次性传传入太多,不相关得到信息

python 复制代码
import os
from dotenv import load_dotenv
from langchain_community.llms import Tongyi
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate, format_document
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import CharacterTextSplitter


# 使用通义千问 api
load_dotenv('key.env')  # 指定加载 env 文件
key = os.getenv('DASHSCOPE_API_KEY')  # 获得指定环境变量
DASHSCOPE_API_KEY = os.environ["DASHSCOPE_API_KEY"]  # 获得指定环境变量
model = Tongyi(temperature=1)

# 检索的文本
content = '采用强酸型阳离子树脂为交换剂的离子交换柱,和经组氨酸基团修饰的强碱型阴离子树脂为交换剂的离子交换层析柱串联,以氯化钠溶液为洗脱剂,对透明质酸粗品进行分离和纯化.得到的透明质酸精品的蛋白质含量低于0.075%,平均分子量大于9.41×105,纯化收率为58%~61%.并对洗脱剂的流速、浓度、pH等条件进行比较,确定了最佳洗脱条件.'

# 加载外部数据
filepath = 'data/专业描述.txt'
raw_documents = TextLoader(filepath, encoding='utf8').load()

# 按行分割块
text_splitter = CharacterTextSplitter(
    chunk_size=100,
    chunk_overlap=20,
    separator="\n",
    length_function=len,
    is_separator_regex=True,
)
documents = text_splitter.split_documents(raw_documents)

# 加载本地 embedding 模型
embedding = HuggingFaceEmbeddings(model_name='bge-small-zh-v1.5')

# 判断向量数据库是否已经创建,创建则加载,否则创建
embedding_db = "./faiss_index"
if os.path.exists(embedding_db):
    print('加载已存在向量数据库')
    db = FAISS.load_local(embedding_db, embedding, allow_dangerous_deserialization=True)
else:
    print('创建向量数据库')
    # 创建向量数据库,把外部数据向量化,保存为数据库到本地
    db = FAISS.from_documents(documents, embedding)
    # 保存
    db.save_local("./faiss_index")

# 构建检索器检索,mmr 检索
retriever = db.as_retriever(search_type="mmr", search_kwargs={'k': 10})  # 构建检索器

# 构建检索回来后的处理函数
# 构建 Document 转文本段落的工具函数
DEFAULT_DOCUMENT_PROMPT = PromptTemplate.from_template(template="{page_content}")
def _combine_documents(docs, document_prompt=DEFAULT_DOCUMENT_PROMPT):
    doc_strings = [format_document(doc, document_prompt) for doc in docs]
    docs = [d.split('\t')[0] for d in doc_strings]
    return docs

# 准备 Model I/O 三元组
template = """找最相关的专业。

请根据以下已知条件:
- 描述:{content}
- 专业列表:{labels}

请遵循以下决策规则:
- 给出的专业必须来自于专业列表中列出的专业。
- 仔细分析描述中出现的专业名词,判断它们是否指向特定的专业。
- 让我们一步一步来思考

请直接回答你认为最相关的专业名称,无需解释说明。
请按照以下格式回答:
- 输出:[专业]

注意:
- 您必须给出回答,不能拒绝回答问题。
- 回答必须简明扼要,不能超出问题所涉及的范围。
"""
prompt = ChatPromptTemplate.from_template(template)

# 构建 RAG 链
chain = (
        {
            "labels": retriever | _combine_documents,  # 把检索回来结果给 _combine_documents 函数处理,提取内容
            "content": RunnablePassthrough()  # 直接作为 content 的值,不做任何操作
        }
        | prompt
        | model
        | StrOutputParser()
)
print(chain.invoke(content))
相关推荐
AI小白龙*2 小时前
LLM大模型实战 —— DB-GPT阿里云部署指南
阿里云·大模型·llm·prompt·embedding·ai大模型·大模型部署
linmoo198620 小时前
检索增强生成RAG系列3--RAG优化之文档处理
embedding·向量数据库·rag·pypdf·文档分块·pdfminer
AGI八零后1 天前
扛鼎中国AI搜索,天工凭什么?
人工智能·学习·机器学习·langchain·llama
嫦娥妹妹等等我1 天前
初识langchain的快速入门指南
langchain
小绵羊不怕大灰狼1 天前
初识LangChain的快速入门指南
langchain
N. LAWLIET2 天前
基于langchain的开源大模型应用开发1
golang·langchain·开源
发菜君3 天前
LangChain真的好用吗?谈一下LangChain封装FAISS的一些坑
人工智能·windows·langchain·大模型·faiss·ai大模型
极客Kimi3 天前
基于Embedding实现超越ES的高级搜索
大数据·elasticsearch·embedding
代码之光_19804 天前
探索LangChain Prompt模板:构建高效语言模型交互的秘诀
语言模型·langchain·prompt
AI小白龙*4 天前
上海交通大学出品《动手学大模型》LLM 实战课,从0入门到精通,附课件+实战教程
人工智能·langchain·大模型·llm·产品经理·ai大模型·动手学大模型