如何用LLM和自有知识库搭建智能agent?

news2024/11/18 23:48:30

用LangChain建立知识库,文末中也推荐其他方案。
项目源码:ChatPDF实现
在这里插入图片描述

LangChain

Indexes使用

对加载的内容进行索引,在indexes中提供了一些功能:

  • Document Loaders,加载文档
  • Text Splitters,文档切分
  • VectorStores,向量存储
  • Retrievers,文档检索

LangChain作为问答可分为4个步骤:

  • Step1,创建索引
  • Step2,从该索引创建Retriever
  • Step3,创建问答链
  • Step4,提问!

ChatTxt实现

LangChain中定义的BaseRetriever,通过get_relevant_documents 函数,可以获取和query相关的文档列表。
在LangChain中使用了Chroma作为向量存储和检索引擎,所以你需要先安装工具箱。

from abc import ABC, abstractmethod
from typing import List
from langchain.schema import Document
class BaseRetriever(ABC):
@abstractmethod
def get_relevant_documents(self, query: str) -> 
List[Document]:
"""Get texts relevant for a query.
Args:
query: string to find relevant texts for
Returns:
List of relevant documents

Chroma是一个用于构建带有embedding的 AI 应用的数据库。

import chromadb
# 获取Chroma Client对象
chroma_client = chromadb.Client()
# 创建Chroma数据集
collection = 
chroma_client.create_collection(name="my_collection")
# 添加数据
collection.add(
documents=["This is an apple", "This is a banana"],
metadatas=[{"source": "my_source"}, {"source": 
"my_source"}],
ids=["id1", "id2"]
)
# 查询数据
results = collection.query(
query_texts=["This is a query document"],
n_results=2
)
results

{‘ids’: [[‘id1’, ‘id2’]],
‘embeddings’: None,
‘documents’: [[‘This is an apple’, ‘This is a banana’]],
‘metadatas’: [[{‘source’: ‘my_source’}, {‘source’: ‘my_source’}]],
‘distances’: [[1.652575969696045, 1.6869373321533203]]}

from langchain.chains import RetrievalQA
from langchain.llms import OpenAI
from langchain.document_loaders import TextLoader
from langchain.indexes import VectorstoreIndexCreator
# 文档加载
loader = TextLoader('./三国演义第1回.txt', encoding='utf8')
# 创建向量索引
index = VectorstoreIndexCreator().from_loaders([loader])
# 检索文档中的内容
query = "桃园三结义是哪三个人"
index.query(query)

更多参考项目源码:
Txt格式实现

LangChain的4种索引方式:

1.stuff
直接把文档作为prompt输入给OpenAI。

2.map_reduce
对于每个chunk做一个prompt(回答或者摘要),然后再做合并。

3.refine
在第一个chunk上做prompt得到结果,然后合并下一个文件再输出结果。

4.map_rerank
对每个chunk做prompt,然后打个分,然后根据分数返回最好的文档中的结果。

ChatPDF实现

方法1

from langchain.document_loaders import PyPDFLoader
from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.document_loaders import UnstructuredPDFLoader
from langchain.llms import OpenAI
from langchain.chains.question_answering import load_qa_chain

# 读取本地知识
loader = UnstructuredPDFLoader("三国演义第一回.pdf")
pages = loader.load_and_split()
embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_documents(pages, embeddings).as_retriever()

query = "桃园三结义都有谁"
docs = docsearch.get_relevant_documents(query)
chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff")
output = chain.run(input_documents=docs, question=query)
print(output)

方法2

相对完整版的ChatPDF:

Step1,生成embedding,保存到本地

1.加载PDF,得到文本 content。
2.将content切分成多个docs,设置每个doc的max_length,比如 max_length=300。
3.设置embedding编码方法,比如OpenAIEmbeddings,并对docs进行embedding。
4.持久化到本地目录,比如 db文件夹

Step2,用户query
1.检索相关docs(可以设置 Topk= 4)
2.使用 load_qa_chain,设置input_documents参数
3.得到Answer

import os
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.document_loaders import TextLoader
from langchain.chains.question_answering import load_qa_chain
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate

# os.environ["OPENAI_API_KEY"] = "{your-api-key}"

global retriever
def load_embedding():
    global retriever
    # 使用OpenAI Embedding
    embedding = OpenAIEmbeddings()
    # 指定了persist_directory, 所以在本地会有db文件夹,保存持久化结果
    vectordb = Chroma(persist_directory='db', embedding_function=embedding)
    # 检索Top4
    retriever = vectordb.as_retriever(search_kwargs={"k": 4})

# 基于query进行问答
def prompt(query):
    prompt_template = """
    请注意:请谨慎评估query与提示的Context信息的相关性,
    只根据本段输入文字信息的内容进行回答,如果query与提供的材料无关,请回答"我不知道",
    另外也不要回答无关答案:
    Context: {context}
    Question: {question}
    Answer:"""
    PROMPT = PromptTemplate(
        input_variables=["context", "question"],
        template=prompt_template
    )
    # 从向量数据库中,检索出Top5相似文档
    docs = retriever.get_relevant_documents(query)
    print('docs=', docs)
    print('len(docs)=', len(docs))
    
    # 基于docs来prompt,返回你想要的内容
    chain = load_qa_chain(ChatOpenAI(temperature=0), chain_type="stuff", prompt=PROMPT)
    result = chain({"input_documents": docs, "question": query}, return_only_outputs=True)
    return result['output_text']
#%%
# 加载embedding
load_embedding()
print('hhhhh')
query = "桃园三结义都有谁"
#query = "曹操都有哪些部将"

print("Query:" + query + '\nAnswer:' + prompt(query) + '\n')

ChatPDF实现原理

加载文件 -> 读取文本-> 文本分割 -> 文本向量化-> 问句向量化 -> 在文本向量中匹配出与问句向量最相似的top k个-> 匹配出的文本作为上下文和问题一起添加到 prompt 中-> 提交给 LLM 生成回答。

在这里插入图片描述

在这里插入图片描述

LangChain + ChatGLM

https://github.com/imClumsyPanda/langchain-ChatGLM

# 加载Google云硬盘
from google.colab import drive
drive.mount('/content/drive’)
# 拉取仓库
%cd /content/drive/MyDrive/chatglm/langchain-ChatGLM
!pip install -r requirements.txt
!pip install gradio==3.28.3
# 下载模型
%cd /content/drive/MyDrive/chatglm/langchain-ChatGLM
!git clone https://huggingface.co/THUDM/chatglm-6b-int4
!git clone https://huggingface.co/GanymedeNil/text2veclarge-chinese
#修改web.py和model_config.py文件
!sed -i 's/share=False/share=True/g' 
/content/drive/MyDrive/chatglm/langchainChatGLM/webui.py
!sed -i 's/GanymedeNil\/text2vec-largechinese/\/content\/drive\/MyDrive\/chatglm\/langchainChatGLM\/text2vec-large-chinese/g' 
/content/drive/MyDrive/chatglm/langchainChatGLM/configs/model_config.py
……

在这里插入图片描述

ChatPDF实现场景

典型的使用场景:

  • 项目经理角色:项目管理文档 + LLM
  • 新车导购角色:新车导购文章 + LLM
  • 二手车专家:二手车鉴定文档 + LLM
  • 老中医角色: 中医问诊文档 + LLM
  • 智能客服:客服聊天记录 + LLM
  • 律师角色:律师咨询记录 + LLM
  • HR角色:考勤绩效手册 + LLM

一个典型的prompt模板

已知信息:
{context} 根据上述已知信息,简洁和专业的来回答用户的问题。如果无法从中得到答案,请说 "根据已知信息无法回答该问题" 或 "没有提供足够的相关信息",不允许在答案中添加编造成分,答案请使用中文。
问题是:{question}

向量数据库

存储embedding的数据库称为向量数据库。ChatGPT中的Transformer结构需要对知识进行Embedding。
在这里插入图片描述
在这里插入图片描述

其他知识库方案

https://chat.openai.com/g/g-V2KIUZSj0-ai-pdf

Ai PDF是基于GPT的一个PDF文档处理工具,具有以下特点:

  • 可以处理体积高达2GB的单个PDF文件,没有限制。
  • 支持在http://myaidrive.com免费账号下上传大量PDF,无需重复上传文件。
  • PRO版本可以在数千个PDF中进行检索,并可以处理扫描的OCR文档。
  • 可以为长度较长的文档生成高质量的摘要。
  • 利用GPT的能力从PDF中提取信息,进行问答。
  • 整体而言,Ai PDF致力于提供PDF文档处理、搜索、摘要和问答等功能,可以节省人工查阅PDF的大量时间,提高工作效率。
  • 该服务正在不断完善中,需要用户签约才能使用ChatGPT进行互动。

https://github.com/imartinez/privateGPT

这是一个开源项目,让用户可以利用GPT的力量与自己的文档进行交互,完全本地运行,不会泄露用户数据。用户可以导入各种文档,然后用自然语言提出问题,GPT会基于这些文档给出回答。

https://github.com/nomic-ai/gpt4all

它提供了开源的GPT聊天机器人,可以在本地环境运行,不需要连接外部API。支持多种编程语言实现,可以自定义训练来优化对话效果。

https://github.com/PromtEngineer/localGPT

这也是一个本地运行GPT模型的开源项目。用户可以将文档导入本地,GPT模型会基于这些文档内容来回答用户提出的问题,保护了用户隐私。

https://filegpt.app/

这是一个商业化的工具,同样可以让用户与各种格式的文档和内容进行自然语言交互,获取精确的回复。它支持PDF、Word文档、文本、音频、视频等多种格式。

https://www.popai.pro/

这是一个面向个人的AI工作空间服务,用户可以自定义训练模型来优化不同的任务,如写作、总结、问答等。它提供了可视化的训练监控界面。主要面向企业用户。

https://www.humata.ai/

Humata是一个利用AI技术让用户可以与各种数据文档进行自然语言交互的工具。

https://askwise.ai/

askwise.ai是一个基于GPT的知识助手服务。

结语

知识就是力量,AI生成筑高楼。

欢迎留言交流!

我是李孟聊AI,独立开源软件开发者,SolidUI作者,对于新技术非常感兴趣,专注AI和数据领域,如果对我的文章内容感兴趣,请帮忙关注点赞收藏,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1384775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Codeforces Round 768 (Div. 1) D. Flipping Range(思维题 等价类性质 dp)

题目 思路来源 官方题解 洛谷题解 题解 可操作的最短区间长度肯定是gcd,记为g,然后考虑如何dp 考虑g个等价类,每个等价类i,ig,i2*g,... 每次翻转长度为g的区间,会同时影响到g个等价类总的翻转的奇偶性, 性质一&…

Puppeteer让你网页操作更简单(2)抓取数据

Puppeteer让你网页操作更简单(1)屏幕截图】 示例2 —— 让我们抓取一些数据 现在您已经了解了Headless Chrome和Puppeteer的工作原理基础知识,让我们看一个更复杂的示例,其中我们实际上可以抓取一些数据。 首先,请查看此处的Puppeteer API文档。如您所见,有大量不同的方法我…

Python教程39:使用turtle画今天日期

---------------turtle源码集合--------------- Python教程36:海龟画图turtle写春联 Python源码35:海龟画图turtle画中国结 Python源码31:海龟画图turtle画七道彩虹 Python源码30:海龟画图turtle画紫色的小熊 Python源码29&a…

10.9.2 std::function 非OO的多态实现 Page185~187

源代码&#xff1a; #include <iostream> #include <functional> #include <list>using namespace std;//使用function模板类定义一个类型&#xff0c; //该类型要求作为T的 //函数类型是参数是string,返回值是void typedef std::function <void (std::s…

MySQL-多表联合查询

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…

【算法实验】实验1

实验1-1 斐波那契数 【问题描述】斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。 定义&#xff1a;F(0) 0, F(1) 1, F(n) F(n-1) F(n-2) 其中n>1 要求计…

1、计算机的硬件组成、校验码

计算机的硬件组成 CPU的组成与功能 CPU的组成 CPU主要是由运算器、控制器、寄存器组和内部总线等部件组成 CPU的功能 1、程序控制通过执行指令来控制程序的执行顺序2、操作功能一条指令的实现需要若干操作信号配合&#xff0c;控制相应的部件完成相对应的操作3、时间控制对…

idea2020.1 x64实现git的push

今天还有点时间&#xff0c;顺便写一下这个。 我这边只说一下远程仓库&#xff08;gitee&#xff09;的push 点击之后会弹出 点击&#xff0c;弹出 输入你定义的远程仓库名&#xff08;自己起&#xff09;&#xff0c;以及url&#xff0c;url由下面获取 在你的gitee创建好仓库…

Marin说PCB之传输线损耗---趋肤效应和导体损耗01

大家在做RF上的PCB走线或者是车载相机的上走线的时候经常会听那些硬件工程师们说你这个走线一定要保证50欧姆的阻抗匹配啊&#xff0c;还有就是记得加粗走做隔层参考。 有的公司的EE硬件同事会很贴心的把RF走线的注意事项给你备注在原理图上或者是layoutguide上&#xff0c;遇到…

Rust-函数

简介 Rust的函数使用关键字fn开头。 函数可以有一系列的输入参数&#xff0c;还有一个返回类型。 函数体包含一系列的语句(或者表达式)。 函数返回可以使用return语句&#xff0c;也可以使用表达式。 Rust编写的可执行程序的入口就是fn main()函数。 以下是一个函数的示例…

Puppeteer让你网页操作更简单(1)屏幕截图

网页自动化设计爬虫工具 中就使用了Puppeteer进行对网页自动化处理&#xff0c;今天就来看看它是什么东西&#xff01; 我们将学习什么? 在本教程中,您将学习如何使用JavaScript自动化和抓取 web。 为此,我们将使用Puppeteer。 Puppeteer是一个Node库API,允许我们控制无头Ch…

在Eureka中注册多个服务(根据本地主机端口号区分)

这篇文章主要介绍如何在Eureka注册中心内注册多个EurekaServer服务端 建项目 创建一个Maven项目&#xff0c;在里面创建三个小的Maven空项目&#xff0c;具体结构如下。 EurekaServer3&#xff0c;即外面的大模块&#xff0c;为了清楚的观察项目结构&#xff0c;我将其src文…

Python data Structures: Strings, Files, Lists

Python data Structures 这门课是在coursera上由美国密歇根大学开展的公开课。python零基础可以选择course1,这是course2&#xff0c;我用来复习和补充的。本章将复习字符串、文件、列表。 Python是这样的&#xff0c;没学一次都有新的发现&#xff0c;补充以前遗漏的地方。 …

助力工业园区作业违规行为检测预警,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建工业园区场景下作业人员违规行为检测识别系统

在很多工业园区生产作业场景下保障合规合法进行作业生产操作&#xff0c;对于保护工人生命安全降低安全隐患有着非常重要的作用&#xff0c;但是往往在实际的作业生产中&#xff0c;因为一个安全观念的淡薄或者是粗心大意&#xff0c;对于纪律约束等意思薄弱&#xff0c;导致在…

开发er们必知的Git命令

Git和GitHub是每位软件工程师都必须了解的最基本的东西。这些工具是开发人员日常工作的组成部分,因为我们每天都要与它们进行交互。熟练掌握Git不仅能简化您的生活,还能显著提高生产力。在这篇博文中,我们将探索一组命令,这些命令将大大提高您的生产力。随着您对这些命令的掌握…

【数据结构】八大排序之计数排序算法

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.计数排序简介及思想 二.计数排序代码实现 三.计数排序复杂度分析 &#x1f4cc;时间复杂度 &#x1f4cc;空间复杂度 结语 一.计数排序简介及思想 计数排序(Cou…

每日一博 - 使用APIFOX调测 @RequestBody标注的对象

文章目录 概述发送 post 请求步骤1.新建接口&#xff0c;设置为 post 请求2. 填写 URL 和参数3.发送请求 实战 RequestBody 概述 APIFOX&#xff08;类似Postman&#xff09;提供了丰富的功能来支持用户发送包含各种信息的 POST 请求&#xff0c;如文本数据、JSON 或 XML 数据…

雷达截面积RCS原理浅析

Radar Cross Section 雷达截面积&#xff08;Radar Cross Section&#xff09;是雷达扫描到物体的等效可见面积。具体来讲&#xff0c;RCS是一个虚拟的平面&#xff0c;该平面可以拦截该区域覆盖范围内的全部雷达能量&#xff0c;并且以漫反射形式将能量反射给雷达。雷达接受到…

在Android原生项目中 创建 Flutter模块

前言 应用场景&#xff1a;在已有的Android原生项目中&#xff0c;引入Flutter模块&#xff0c;摸索了两天&#xff0c;终于给整出来了&#xff1b; 如果是新项目&#xff0c;最好直接创建Flutter项目&#xff0c;然后在Fluter的 android / ios目录中&#xff0c;写原生代码&…

MYSQL的事务隔离

本章概览 mysql是一个支持多引擎的系统&#xff0c;并不是所有引擎都支持事务&#xff0c;本篇以innodb为例解析mysql在事务支持的实现。提到事务一定会想到ACID(Atomicity、Consistency、Isolation、Durability&#xff0c;即原子性、一致性、隔离性、持久性)&#xff0c;今天…