目录
示例代码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))