当前位置:   article > 正文

LangChain(一)构建本地数据检索问答Agent,新手向_qianfan.chatcompletion() 指定参考资料

qianfan.chatcompletion() 指定参考资料

如果是想要从头开始了解本专栏,建议直接从第二篇开始。

系列文章目录链接

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博客

  1. from langchain_text_splitters import RecursiveCharacterTextSplitter
  2. import qianfan
  3. # 文本分割器
  4. text_splitter = RecursiveCharacterTextSplitter(
  5. chunk_size=100,
  6. chunk_overlap=20,
  7. length_function=len,
  8. is_separator_regex=False,
  9. separators=[
  10. "\n\n",
  11. "\n",
  12. " ",
  13. ".",
  14. ",",
  15. "\u200B", # Zero-width space
  16. "\uff0c", # Fullwidth comma
  17. "\u3001", # Ideographic comma
  18. "\uff0e", # Fullwidth full stop
  19. "\u3002", # Ideographic full stop
  20. "",
  21. ],
  22. )
  23. # 文本嵌入计算器
  24. embeddings = qianfan.Embedding()
  25. # 初始化一个空列表来存储文件中的每一行
  26. database_words = []
  27. # 使用with语句打开文件
  28. with open('./database/sourse_data/txt/database001.txt', 'r', encoding='utf-8') as file:
  29. # 遍历文件的每一行
  30. for line in file:
  31. # 去除换行符'\n',然后添加
  32. database_words.append(line.strip())
  33. def get_embedding_vectors(text_splitter, embeddings, data):
  34. # 文本分割
  35. split_docs = text_splitter.create_documents(data)
  36. # 获取文本列表
  37. data_list = []
  38. for data_doc in split_docs:
  39. data_list.append(data_doc.page_content)
  40. # 计算嵌入向量
  41. vectors = embeddings.do(model="Embedding-V1",texts = data_list).body
  42. return vectors
  43. # 获取到本地知识库的向量表示
  44. vectors = get_embedding_vectors(text_splitter, embeddings, database_words)
  45. # 保存数据
  46. #function.save_json("./database/vectors/vectors.json", vectors)

 步骤二:加载本地数据集

需要加载两个数据集,一个是向量表示的,一个是文本表示的。下标id保持一致即可,亦或者在步骤一的时候你直接构建一个整合的数据集也行。

  1. # 向量表示数据库
  2. vectors_database = function.load_json("./database/vectors/vectors.json")["data"]
  3. # 初始化一个空列表来存储文件中的每一行
  4. database_words = []
  5. # 使用with语句打开文件
  6. with open('./database/sourse_data/txt/database001.txt', 'r', encoding='utf-8') as file:
  7. # 遍历文件的每一行
  8. for line in file:
  9. # 去除换行符'\n',然后添加
  10. database_words.append(line.strip())

 步骤三:构建聊天大模型,并参考本地知识

  1. # 创建聊天器
  2. chat_comp = qianfan.ChatCompletion()
  3. # 获取用户输入
  4. custom_message = input("用户:")
  5. # 进入问答循环
  6. while custom_message != "退出":
  7. # 文本分割
  8. vector = get_embedding_vectors(text_splitter, embeddings, [custom_message])["data"][0]
  9. # 获取相似度最高的n个文本数据
  10. top_n_similarities = function.get_max_n_similarity(vector, vectors_database, 2)
  11. # 将这些文本数据链接在一起
  12. txt = ""
  13. for id, similarity in top_n_similarities:
  14. if similarity < 0.2:
  15. continue
  16. print("similarity = ", similarity)
  17. txt = txt + database_words[id]
  18. prompt = custom_message + "你搜索到的信息如下,可以参考,也可以不参考:" + txt
  19. #print("prompt = ", prompt)
  20. # 指定特定模型
  21. resp = chat_comp.do(
  22. model="ERNIE-Speed-128K",
  23. messages=[{
  24. "role": "user",
  25. "content": prompt
  26. }],
  27. system="你是千天夜编写的私人助手,名字叫小黑", # system为该模型的人设
  28. stream=True
  29. )
  30. for r in resp:
  31. print(r["body"]["result"])
  32. # 获取用户输入
  33. custom_message = input("用户:")

代码全贴! 

文件1:function.py

  1. import json
  2. import numpy as np
  3. from numpy.linalg import norm
  4. # 保存json文件
  5. def save_json(save_path,data):
  6. assert save_path.split('.')[-1] == 'json'
  7. with open(save_path,'w') as file:
  8. json.dump(data,file)
  9. # 加载json文件
  10. def load_json(file_path):
  11. assert file_path.split('.')[-1] == 'json'
  12. with open(file_path,'r') as file:
  13. data = json.load(file)
  14. return data
  15. def get_similarity(list1, list2):
  16. return np.dot(np.array(list1), np.array(list2))/(norm(np.array(list1))*norm(np.array(list2)))
  17. def get_max_n_similarity(dict, database, n):
  18. similarities = []
  19. for i, dic in enumerate(database):
  20. similarity = get_similarity(dict["embedding"], dic["embedding"])
  21. similarities.append((i, similarity ))
  22. similarities.sort(key=lambda x: x[1], reverse=True)
  23. top_n_similarities = similarities[:n]
  24. return top_n_similarities

文件2: get_embedding_vectors.py

  1. def get_embedding_vectors(text_splitter, embeddings, data):
  2. # 文本分割
  3. split_docs = text_splitter.create_documents(data)
  4. # 获取文本列表
  5. data_list = []
  6. for data_doc in split_docs:
  7. data_list.append(data_doc.page_content)
  8. # 计算嵌入向量
  9. vectors = embeddings.do(model="Embedding-V1",texts = data_list).body
  10. return vectors

文件3: main.py

  1. '''
  2. 文件说明:问答大模型主入口
  3. 代号:agent1
  4. 编写者:千天夜
  5. 编写日期:2024.07.02
  6. '''
  7. from langchain.document_loaders import DirectoryLoader
  8. from langchain_text_splitters import CharacterTextSplitter
  9. from langchain_text_splitters import RecursiveCharacterTextSplitter
  10. import qianfan
  11. import os
  12. import function
  13. import json
  14. from get_embedding_vectors import get_embedding_vectors
  15. # 设定百度千帆大模型的AK和SK
  16. os.environ["QIANFAN_AK"] = "AK"
  17. os.environ["QIANFAN_SK"] = "SK"
  18. # 文本分割器
  19. text_splitter = RecursiveCharacterTextSplitter(
  20. chunk_size=100,
  21. chunk_overlap=20,
  22. length_function=len,
  23. is_separator_regex=False,
  24. separators=[
  25. "\n\n",
  26. "\n",
  27. " ",
  28. ".",
  29. ",",
  30. "\u200B", # Zero-width space
  31. "\uff0c", # Fullwidth comma
  32. "\u3001", # Ideographic comma
  33. "\uff0e", # Fullwidth full stop
  34. "\u3002", # Ideographic full stop
  35. "",
  36. ],
  37. )
  38. # 初始化一个空列表来存储文件中的每一行
  39. database_words = []
  40. # 使用with语句打开文件
  41. with open('./database/sourse_data/txt/database001.txt', 'r', encoding='utf-8') as file:
  42. # 遍历文件的每一行
  43. for line in file:
  44. # 去除换行符'\n',然后添加
  45. database_words.append(line.strip())
  46. # 文本嵌入计算器
  47. embeddings = qianfan.Embedding()
  48. '''
  49. step1:构建嵌入向量数据库
  50. '''
  51. #vectors = get_embedding_vectors(text_splitter, embeddings, database_words)
  52. #function.save_json("./database/vectors/vectors.json", vectors)
  53. '''
  54. step2: 加载本地数据集,文本数据集&向量数据集
  55. '''
  56. vectors_database = function.load_json("./database/vectors/vectors.json")["data"]
  57. '''
  58. step3:构建聊天大模型,参考本地资料
  59. '''
  60. # 创建聊天器
  61. chat_comp = qianfan.ChatCompletion()
  62. # 获取用户输入
  63. custom_message = input("用户:")
  64. # 进入问答循环
  65. while custom_message != "退出":
  66. # 文本分割
  67. vector = get_embedding_vectors(text_splitter, embeddings, [custom_message])["data"][0]
  68. top_n_similarities = function.get_max_n_similarity(vector, vectors_database, 2)
  69. txt = ""
  70. for id, similarity in top_n_similarities:
  71. if similarity < 0.2:
  72. continue
  73. print("similarity = ", similarity)
  74. txt = txt + database_words[id]
  75. prompt = custom_message + "你搜索到的信息如下,可以参考,也可以不参考,但是请不要让用户知道你搜索了这些信息:" + txt
  76. #print("prompt = ", prompt)
  77. # 指定特定模型
  78. resp = chat_comp.do(
  79. model="ERNIE-Speed-128K",
  80. messages=[{
  81. "role": "user",
  82. "content": prompt
  83. }],
  84. system="你是千天夜编写的私人助手,名字叫小黑",
  85. stream=True
  86. )
  87. for r in resp:
  88. print(r["body"]["result"])
  89. # 获取用户输入
  90. custom_message = input("用户:")
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/929301
推荐阅读
相关标签
  

闽ICP备14008679号