Python+Milvus+Ollama实现RAG链问答
·
一,下载 Milvus 和 Ollama
请看别的专门的教程
windows 环境下安装 Milvus_windows安装milvus-CSDN博客
二,Milvus 建表
Attu 能提供图形化界面操作,但实际使用时有 bug,比如我不能创建 varchar 字段,这里演示用python 建表和插入,Attu 的其他操作还行能用。
建表:
from pymilvus import connections, Collection, utility
from langchain_ollama import OllamaEmbeddings, OllamaLLM
from langchain_milvus.vectorstores import Milvus
from langchain.chains import RetrievalQA
def create_collection(database_name: str, collection_name: str):
connections.connect(host='localhost', port='19530', db_name=database_name)
if utility.has_collection(collection_name):
print(f"集合 {collection_name} 已存在,终止")
return
fields = [
FieldSchema(name="id", dtype=DataType.VARCHAR, is_primary=True, max_length=256, description="主键"),
FieldSchema(name="vectors", dtype=DataType.FLOAT_VECTOR, dim=768, description="向量"),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=256, description="内容"),
]
schema = CollectionSchema(fields, description="schema")
collection = Collection(name=collection_name, schema=schema)
# 创建索引
if not collection.has_index():
index_params = {
"index_type": "HNSW",
"metric_type": "L2",
"params": {
"M": 16,
"efConstruction": 512
}
}
collection.create_index(
field_name="vectors",
index_params=index_params
)
collection 就相当于表,一定记得创建索引,否则无法搜索。
三,准备 Ollama 模型
需要准备一个 embedding 模型,用来把文字转化为向量。
还需要一个 llm 模型,用来对话。
下载方法请搜索 Ollama 的教程。
四,插入
用 Ollama 的向量模型计算向量:
from langchain_ollama import OllamaEmbeddings
EMBED_MODEL_NAME = "nomic-embed-text:v1.5"
class Embed:
def __init__(self):
self.embedding = OllamaEmbeddings(model=EMBED_MODEL_NAME)
def get_vectors(self, prompts: list[str]) -> list[list[float]]:
# 维度 768
return self.embedding.embed_documents(prompts)
得到向量后将向量数组填入vectors,id就填入id,反正字段根据自己需求自己设计,最后都放入一个 dict,就是下面的 dataa, 可以批量导入,格式是
{
id: [data_1_id, data_2_id, ...],
vectors: [[data_1_vector1, data_1_vector2, ...],[data_2_vector1, data_2_vector2, ...], ...],
text: [data_1_text, data_2_text, ...]
}
插入:
def insert(collection_name, dataa):
connections.connect(host='localhost', port='19530')
collection = Collection(collection_name)
collection.insert(dataa)
collection.load()
五,构建RAG链
from pymilvus import connections, Collection, utility
from langchain_ollama import OllamaEmbeddings, OllamaLLM
from langchain_milvus.vectorstores import Milvus
from langchain.chains import RetrievalQA
def call(question: str):
qa_chain = __get_qa_chain("default", "my_collection")
response = qa_chain.invoke({"query": question})
return f"{response["result"]}\n资料饮用为:\n{response["source_documents"][0].page_content}\n"
def __get_qa_chain(database_name: str, collection_name: str):
# 你的 milvus 服务器
host = "localhost"
port = 19530
connections.connect(
alias=database_name,
host=host,
port=port
)
if not utility.has_collection(collection_name):
raise ValueError(f"Collection '{collection_name}' does not exist")
# 得到 collection 对象
milvus_collection = Collection(collection_name)
milvus_collection.load()
# 你的 Ollama 向量模型
embeddings = OllamaEmbeddings(model=YOUR_EMBED_MODEL_NAME)
# 封装 Milvus 检索器
vector_db = Milvus(
embedding_function=embeddings,
collection_name=collection_name,
connection_args={"host": host, "port": port},
consistency_level="Strong",
vector_field="vectors",
enable_dynamic_field=True,
text_field="text"
)
# 你的 Ollama 大语言模型
llm = OllamaLLM(model=YOUR_OLLAMA_LLM_MODEL_NAME)
# 构建 RAG 链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vector_db.as_retriever(
search_kwargs={
"k": 3,
"param": {
"metric_type": "L2"
}
}
),
chain_type="stuff",
return_source_documents=True
)
return qa_chain
六,注意
如果出现莫名奇妙的报错,把这些东西都试着更新到最新版试试。
如果出现报错:向量字段无法作为输出属性,请更新 milvus 版本
如果想控制输出字段 `output_fields`,不要听信Ai:
search_kwargs={
"k": 3,
"param": {
"metric_type": "L2"
"output_fields": ["1", "2", ...] # 错的,用不了
}
}
会因为重复设置 output_fields 而报错,源码里面已经硬编码了一次设置 output_fields ,不知道 Ai 哪编出来能这样设置的。
如果真想,这两个神秘属性可以控制输出哪个字段(在封装 Milvus 检索器那部分)
enable_dynamic_field=True,
text_field="text"
更多推荐


所有评论(0)