AI的学习之路_9_向量
向量存储

内部向量存储
看一个csv文件
source,info
cpp,是一个面向对象的语言
java,是一个面向对象的语言
c,是一个面向过程的语言
ltskf,是一个面向结果的语言
这个可以理解为如下的表格
| sourcef | info |
|---|---|
| cpp | 是一个面向对象的语言 |
| java | 是一个面向对象的语言 |
| c | 是一个面向过程的语言 |
| ltskf | 是一个面向结果的语言 |
进行一下向量的增加删除和检索
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.document_loaders import CSVLoader
vector_store = InMemoryVectorStore(
embedding=DashScopeEmbeddings() # 传入文本转向量的模型
)
csv_loader = CSVLoader(
file_path="./data/info.csv",
encoding="utf-8",
source_column="source", # 指定某一列为数据来源
)
docs = csv_loader.load()
# 向量存储的新增 删除 检索
vector_store.add_documents(
documents=docs, # 被添加的文档 类型是list[Document]
ids=["id" + str(i) for i in range(1, len(docs) + 1)] # 给提供的文档添加id(字符串) list[str]
)
# 删除 传入id即可
vector_store.delete("id2")
# 检索 返回类型为[Document]
res = vector_store.similarity_search(
"ltskf", # 检索的关键词
2 # 这个k表示检索的结果要几个
)
print(res)
看一下结果

但这只能存在内存里面,程序结束就没了
外部向量存储
from langchain_chroma import Chroma
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.document_loaders import CSVLoader
# Chroma向量数据库
vector_store = Chroma(
collection_name="test", # 当前向量存储起个名字,类似于表名
embedding_function=DashScopeEmbeddings(), # 提供向量模型
persist_directory="./data/chroma_db" # 指定数据存放的文件夹
)
csv_loader = CSVLoader(
file_path="./data/info.csv",
encoding="utf-8",
source_column="source", # 指定某一列为数据来源
)
docs = csv_loader.load()
# 向量存储的新增 删除 检索
vector_store.add_documents(
documents=docs, # 被添加的文档 类型是list[Document]
ids=["id" + str(i) for i in range(1, len(docs) + 1)] # 给提供的文档添加id(字符串) list[str]
)
# 删除 传入id即可
vector_store.delete("id2")
# 检索 返回类型为[Document]
res = vector_store.similarity_search(
"ltskf", # 检索的关键词
2 # 这个k表示检索的结果要几个
)
print(res)
观察代码会发现只有创建的存储对象不同了,其余代码没有区别
允许结果如下

其中,对应文件夹下会出现相应的数据库

测试一下有没有成功
from langchain_chroma import Chroma
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.document_loaders import CSVLoader
# Chroma向量数据库
vector_store = Chroma(
collection_name="test", # 当前向量存储起个名字,类似于表名
embedding_function=DashScopeEmbeddings(), # 提供向量模型
persist_directory="./data/chroma_db" # 指定数据存放的文件夹
)
# csv_loader = CSVLoader(
# file_path="./data/info.csv",
# encoding="utf-8",
# source_column="source", # 指定某一列为数据来源
# )
#
# docs = csv_loader.load()
#
#
# # 向量存储的新增 删除 检索
# vector_store.add_documents(
# documents=docs, # 被添加的文档 类型是list[Document]
# ids=["id" + str(i) for i in range(1, len(docs) + 1)] # 给提供的文档添加id(字符串) list[str]
# )
#
# # 删除 传入id即可
# vector_store.delete("id2")
# 检索 返回类型为[Document]
res = vector_store.similarity_search(
"ltskf", # 检索的关键词
2 # 这个k表示检索的结果要几个
)
print(res)

结果一模一样
可以看一下数据库里面的样子

# 检索 返回类型为[Document]
res = vector_store.similarity_search(
"ltskf", # 检索的关键词
2, # 这个k表示检索的结果要几个
filter={"source": "lstkf"}
)
这样写可以过滤,只要ltskf的数据
实战一下
接下来以我的个人笔记进行一下简单的实战操作,让大模型在我的私人笔记里面找东西,然会回复我
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_chroma import Chroma
from 长期会话记忆 import printf_prompt
# 加载模型
model = ChatTongyi(model="qwen-max")
# 提供聊天模版
prompt = ChatPromptTemplate.from_messages(
[
("system", "以我提供的参考内容为主,简约的专业的回答我所提供的问题。参考资料{context}"),
("user", "用户提问{input}")
]
)
# 提供向量模型 创建存储库
vector_store = Chroma(
collection_name="STL",
embedding_function=DashScopeEmbeddings(),
persist_directory="./data/MyNote_db"
)
# 创建一个pdf加载器
loader = PyPDFLoader(
file_path="./data/STL.pdf",
mode='page'
)
# 这边一边懒加载一边存入数据库中
i = 1
for page_pdf in loader.lazy_load():
vector_store.add_documents(
documents=[page_pdf],
ids=["id" + str(i)] # 给提供的文档添加id(字符串) list[str]
)
print(f"第{i}页存入了数据库")
i += 1
# 这里定义一下用户的提问
user_question = "vector怎么移除元素"
# 检索向量库
res = vector_store.similarity_search(user_question, 3)
# 构建参考资料
context = "["
for doc in res:
context += doc.page_content
context += " "
context += "]"
# 输出提示词来调试使用
def print_prompt(prompt):
print(prompt.to_string())
print("-" * 20)
return prompt
# 构建执行链条
chain = prompt | print_prompt | model | StrOutputParser()
# 执行链
ai_res = chain.invoke({"input": user_question, "context": context})
print(ai_res)
看一下输出结果

RunnablePassthrough的使用
将向量的检索加入链中
看一下对上述代码的改装
from langchain_core.documents import Document
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_chroma import Chroma
from langchain_core.runnables import RunnablePassthrough
from 长期会话记忆 import printf_prompt
# 加载模型
model = ChatTongyi(model="qwen-max")
# 提供聊天模版
prompt = ChatPromptTemplate.from_messages(
[
("system", "以我提供的参考内容为主,简约的专业的回答我所提供的问题。参考资料{context}"),
("user", "用户提问{input}")
]
)
# 提供向量模型 创建存储库
vector_store = Chroma(
collection_name="STL",
embedding_function=DashScopeEmbeddings(),
persist_directory="./data/MyNote_db"
)
# 这里定义一下用户的提问
user_question = "vector怎么获取长度"
# 使用新的向量检索函数 返回一个Runable接口的子类示例对象
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
def format_func(docs: list[Document]):
if not docs:
return "无参考资料"
formatted_str = "["
for doc in docs:
formatted_str += doc.page_content
formatted_str += "]"
# 构建新的链
chain = (
{"input": RunnablePassthrough(), "context": retriever | format_func} | prompt | model | StrOutputParser()
)
# 执行链
ai_res = chain.invoke(user_question)
print(ai_res)

可见依然从stl笔记里面取出来相关内容
其中比较有难度的就是那个新的链了
chain = (
{"input": RunnablePassthrough(), "context": retriever | format_func} | prompt | model | StrOutputParser()
)


浙公网安备 33010602011771号