赞
踩
LangChain(二)基础问答大模型,纯新手向-CSDN博客
LangChain(三)基础问答大模型,从LLMchain开始了解chain!纯新手向-CSDN博客
LangChain(四)工具调用的底层原理!给大模型按上双手吧!(新手向)-CSDN博客
在如今大模型如火如荼的现在,作为算法工程师,不整点AI大模型怎么说得过去,然而作为一个纯纯的门外汉,两眼一抹黑。在此摸着石头过河,留下细微足迹,以便后来人参考和嘲笑。
LangChain是一个高度抽象的AI工具,集成了诸多功能包括(文本嵌入、LLM、检索工具……),并且通过链(chain)的方式串联在一起,以期实现诸多功能。
在24年,LangChain已经不如23年那么火。很多AI领域的大牛开始抨击LangChain过于高层抽象,不方便修改底层逻辑。但是这和我们这种小白有什么关系呢?毕竟我们又不修改底层逻辑。对于我们小白来说自然是越方便越好。Langchain的入门门槛较低,容易上手,而且有丰富的社区问答资源,所以我的首选依旧是Langchain。
由于langchain高度抽象,对于第一次学习来说,最好还是自己写一点比较好,下面的例子我把一些langchain的部分自己重写了。
对于本地问答大模型的构建,关键在于如何对本地数据库进行检索。大致流程如下:
1. 用户输入 | 2. 本地检索知识库 | 3. 构建prompt(用户输入+本地知识)并传递给大模型 | 4. 获取语言大模型回复 |
当然在上诉流程之前,需要对本地的知识库进行文本嵌入向量化处理。
就是对本地知识库进行文本嵌入计算获取向量表示
对于文本嵌入的相关知识可以参考本博主的这篇文章:
基于M3E模型的文本句嵌入与文本分类----提高语音技术的泛化能力_m3e 模型加载-CSDN博客
- from langchain_text_splitters import RecursiveCharacterTextSplitter
- import qianfan
-
- # 文本分割器
- text_splitter = RecursiveCharacterTextSplitter(
- chunk_size=100,
- chunk_overlap=20,
- length_function=len,
- is_separator_regex=False,
- separators=[
- "\n\n",
- "\n",
- " ",
- ".",
- ",",
- "\u200B", # Zero-width space
- "\uff0c", # Fullwidth comma
- "\u3001", # Ideographic comma
- "\uff0e", # Fullwidth full stop
- "\u3002", # Ideographic full stop
- "",
- ],
- )
-
- # 文本嵌入计算器
- embeddings = qianfan.Embedding()
-
- # 初始化一个空列表来存储文件中的每一行
- database_words = []
-
- # 使用with语句打开文件
- with open('./database/sourse_data/txt/database001.txt', 'r', encoding='utf-8') as file:
- # 遍历文件的每一行
- for line in file:
- # 去除换行符'\n',然后添加
- database_words.append(line.strip())
-
- def get_embedding_vectors(text_splitter, embeddings, data):
-
- # 文本分割
- split_docs = text_splitter.create_documents(data)
-
- # 获取文本列表
- data_list = []
- for data_doc in split_docs:
- data_list.append(data_doc.page_content)
-
- # 计算嵌入向量
- vectors = embeddings.do(model="Embedding-V1",texts = data_list).body
- return vectors
-
- # 获取到本地知识库的向量表示
- vectors = get_embedding_vectors(text_splitter, embeddings, database_words)
- # 保存数据
- #function.save_json("./database/vectors/vectors.json", vectors)
需要加载两个数据集,一个是向量表示的,一个是文本表示的。下标id保持一致即可,亦或者在步骤一的时候你直接构建一个整合的数据集也行。
- # 向量表示数据库
- vectors_database = function.load_json("./database/vectors/vectors.json")["data"]
-
- # 初始化一个空列表来存储文件中的每一行
- database_words = []
-
- # 使用with语句打开文件
- with open('./database/sourse_data/txt/database001.txt', 'r', encoding='utf-8') as file:
- # 遍历文件的每一行
- for line in file:
- # 去除换行符'\n',然后添加
- database_words.append(line.strip())
- # 创建聊天器
- chat_comp = qianfan.ChatCompletion()
-
- # 获取用户输入
- custom_message = input("用户:")
-
- # 进入问答循环
- while custom_message != "退出":
- # 文本分割
- vector = get_embedding_vectors(text_splitter, embeddings, [custom_message])["data"][0]
- # 获取相似度最高的n个文本数据
- top_n_similarities = function.get_max_n_similarity(vector, vectors_database, 2)
-
- # 将这些文本数据链接在一起
- txt = ""
- for id, similarity in top_n_similarities:
- if similarity < 0.2:
- continue
- print("similarity = ", similarity)
- txt = txt + database_words[id]
-
- prompt = custom_message + "你搜索到的信息如下,可以参考,也可以不参考:" + txt
- #print("prompt = ", prompt)
-
- # 指定特定模型
- resp = chat_comp.do(
- model="ERNIE-Speed-128K",
- messages=[{
- "role": "user",
- "content": prompt
- }],
- system="你是千天夜编写的私人助手,名字叫小黑", # system为该模型的人设
- stream=True
- )
-
- for r in resp:
- print(r["body"]["result"])
-
- # 获取用户输入
- custom_message = input("用户:")
- import json
- import numpy as np
- from numpy.linalg import norm
-
- # 保存json文件
- def save_json(save_path,data):
- assert save_path.split('.')[-1] == 'json'
- with open(save_path,'w') as file:
- json.dump(data,file)
-
- # 加载json文件
- def load_json(file_path):
- assert file_path.split('.')[-1] == 'json'
- with open(file_path,'r') as file:
- data = json.load(file)
-
- return data
-
- def get_similarity(list1, list2):
- return np.dot(np.array(list1), np.array(list2))/(norm(np.array(list1))*norm(np.array(list2)))
-
- def get_max_n_similarity(dict, database, n):
-
- similarities = []
-
- for i, dic in enumerate(database):
- similarity = get_similarity(dict["embedding"], dic["embedding"])
-
- similarities.append((i, similarity ))
-
- similarities.sort(key=lambda x: x[1], reverse=True)
-
- top_n_similarities = similarities[:n]
-
- return top_n_similarities
- def get_embedding_vectors(text_splitter, embeddings, data):
-
- # 文本分割
- split_docs = text_splitter.create_documents(data)
-
- # 获取文本列表
- data_list = []
- for data_doc in split_docs:
- data_list.append(data_doc.page_content)
-
- # 计算嵌入向量
- vectors = embeddings.do(model="Embedding-V1",texts = data_list).body
- return vectors
- '''
- 文件说明:问答大模型主入口
- 代号:agent1
- 编写者:千天夜
- 编写日期:2024.07.02
- '''
- from langchain.document_loaders import DirectoryLoader
- from langchain_text_splitters import CharacterTextSplitter
- from langchain_text_splitters import RecursiveCharacterTextSplitter
- import qianfan
- import os
- import function
- import json
- from get_embedding_vectors import get_embedding_vectors
-
- # 设定百度千帆大模型的AK和SK
- os.environ["QIANFAN_AK"] = "AK"
- os.environ["QIANFAN_SK"] = "SK"
-
- # 文本分割器
- text_splitter = RecursiveCharacterTextSplitter(
- chunk_size=100,
- chunk_overlap=20,
- length_function=len,
- is_separator_regex=False,
- separators=[
- "\n\n",
- "\n",
- " ",
- ".",
- ",",
- "\u200B", # Zero-width space
- "\uff0c", # Fullwidth comma
- "\u3001", # Ideographic comma
- "\uff0e", # Fullwidth full stop
- "\u3002", # Ideographic full stop
- "",
- ],
- )
-
- # 初始化一个空列表来存储文件中的每一行
- database_words = []
-
- # 使用with语句打开文件
- with open('./database/sourse_data/txt/database001.txt', 'r', encoding='utf-8') as file:
- # 遍历文件的每一行
- for line in file:
- # 去除换行符'\n',然后添加
- database_words.append(line.strip())
-
- # 文本嵌入计算器
- embeddings = qianfan.Embedding()
-
- '''
- step1:构建嵌入向量数据库
- '''
- #vectors = get_embedding_vectors(text_splitter, embeddings, database_words)
- #function.save_json("./database/vectors/vectors.json", vectors)
-
-
- '''
- step2: 加载本地数据集,文本数据集&向量数据集
- '''
-
-
- vectors_database = function.load_json("./database/vectors/vectors.json")["data"]
-
-
- '''
- step3:构建聊天大模型,参考本地资料
- '''
- # 创建聊天器
- chat_comp = qianfan.ChatCompletion()
-
- # 获取用户输入
- custom_message = input("用户:")
-
- # 进入问答循环
- while custom_message != "退出":
- # 文本分割
- vector = get_embedding_vectors(text_splitter, embeddings, [custom_message])["data"][0]
-
- top_n_similarities = function.get_max_n_similarity(vector, vectors_database, 2)
-
- txt = ""
- for id, similarity in top_n_similarities:
- if similarity < 0.2:
- continue
- print("similarity = ", similarity)
- txt = txt + database_words[id]
-
- prompt = custom_message + "你搜索到的信息如下,可以参考,也可以不参考,但是请不要让用户知道你搜索了这些信息:" + txt
- #print("prompt = ", prompt)
-
- # 指定特定模型
- resp = chat_comp.do(
- model="ERNIE-Speed-128K",
- messages=[{
- "role": "user",
- "content": prompt
- }],
- system="你是千天夜编写的私人助手,名字叫小黑",
- stream=True
- )
-
- for r in resp:
- print(r["body"]["result"])
-
- # 获取用户输入
- custom_message = input("用户:")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。