简介

了解到

  • 什么是大型语言模型
  • 什么是Langchain 一个框架,开发基于大模型语言为基础的应用 智能体,问答系统等,通过langchain统一的去调用ai大模型
  • 如何利用Langchain 开发AI应用

场景:
1.用户提问–> 大模型----->输出
2.用户提问—>提示词模版 + 大模型 ------>输出
3.用户提问—>提示词模版 + 大模型 + 记忆 ------>输出
4.用户提问—>提示词模版 + 大模型 + 记忆+工具 ------>输出
5.用户提问—>提示词模版 + 大模型 + 记忆+工具+向量化数据库 ------>输出

1.什么是大型语言模型 = 鹦鹉学舌

人工智能的一种工具,用来解析自然语言,达到与机器的i一个自然对话,
语言模型有很多 ,大型的意思就是指回答的更加全面,例如天气类app你问天气,他可能只会回答天气相关的东西

2.为什么要使用langchain

大模型有一些弊端,无法直接联网,训练的数据有截止时间,无法访问第三方api,也没法记录私有数据, 所有就需要langchain
这其实就是一个基础deepseek大模型的一个应用程序
在这里插入图片描述

2.RAG架构 解锁增强生成

精准解决 大模型知识冻结 和 大模型知识幻觉的问题

3.Agent

Agent =llm 大语言模型 + Toos 工具 + memroy 记忆能力 + planning 决策能力 +Action 行动能力
能不能用工具 来区分 是智能体 还是 大模型

4.安装jupyter notebook + langchain

1.pycharm 新建项目
2.pip install jupyter
3.pip install langchain

5.选择chatGPT 官网获取密钥

官网选择登陆 https://openai.com/zh-Hans-CN/api/
登陆选择API平台,然后就是注册登陆,然后创建API key
在这里插入图片描述

6.使用PoloAPI 国内访问openai模型 或者 使用closeai (推荐)

PoloAPI有点坑用了两天账号被封了
https://poloai.top/console/token
直接注册 创建令牌。 需要冲点钱
在这里插入图片描述

6.创建一个llm模块

1.项目根目录下创建一个 .env文件

OPENAI_API_KEY = “sk-xxxxxxx”
OPENAI_BASE_URL = “https://poloai.top/v1”

import os
import dotenv
from langchain_openai import OpenAI

dotenv.load_dotenv()
llm = OpenAI()
str1 = llm.invoke('写一首春天的诗')
print(str1)

在这里插入图片描述

3.模型调用的分类

角度1:
非对话模型: LLMs Text Model 仅支持单次对话,不支持上下文
对话模型: Chat Models (推荐)
嵌入模式: Embedding models

角度2:按照模型调用时,参数书写位置的不同 api-key base_url model-name
硬编码方式:将参数写在代码中
使用环境变量
使用配置文件 (推荐)

角度3: 具体api的调用
使用langchain 提供的API (推荐)
使用OpenAI 官方提供的API
使用其他平台提供的API

参数
model=“gpt-4o-mini”, #默认使用的是 gpt-3.5-turbo 模型
base_url=“https://poloai.top/v1”,
api_key=“sk-ZuJxxxx”
temperature=0, #控制模型输出随机性 0 的话 每次输出都是一样的 建议 0.3,0.5精准模式 0.8平衡模式 1创意模式
max_tokens=20

1.非对话模型

import os
import dotenv
from langchain_openai import OpenAI

dotenv.load_dotenv()
llm = OpenAI()
str1 = llm.invoke('写一首春天的诗')
print(str1)

2.对话模型

#对话模式
from langchain_openai import ChatOpenAI
import dotenv

# dotenv.load_dotenv()
# 调用对话模型
# chat_model = ChatOpenAI(
#     # model="gpt-4o-mini", #默认使用的是 gpt-3.5-turbo 模型
#     base_url="https://poloai.top/v1",
#     api_key="sk-ZuJczuFpKnBHYyHNpVQlcd91BFPIY0Yn34OgANeb7bxkVMAC"
# )

chat_model = ChatOpenAI(
#     其他参数
    temperature=0, #控制模型输出随机性 0 的话 每次输出都是一样的 建议 0.3,0.5精准模式 0.8平衡模式 1创意模式
    max_tokens=20

)

res = chat_model.invoke('理想L6这车多少钱?')

print(res.content)

在这里插入图片描述

7.体会使用各个平台api

1.百度千帆平台
2.阿里云百炼平台
3.智谱的GLM
4。硅基流动平台

8.模型调用

消息列表 SystemMessage,HumanMessage AIMessage
多轮对话 大模型本身是没有记忆能力的

from langchain_core.messages import SystemMessage,HumanMessage,AIMessage

syste_message = SystemMessage(content='你是一个英语专家嘛',additional_kwargs={"tool":"invoke_func1"})
human_message = HumanMessage(content='帮我定制一个英语六级学习计划')
# ai_message = AIMessage(content = '我不致痘')
message = [syste_message,human_message]  # 只回答最后一个问题

print(message)

res1 = chat_model.invoke(message)
print(res1.content)

模型调用方法:

1.invoke()/stream() 阻塞式 非流式输出 流失输出
2.batch() 批量
3.ainvoke()/astream() 异步 阻塞式

batch

message = [HumanMessage(content='梦幻西游手游好玩嘛')]
message1 = [HumanMessage(content='今年什么新能源车很火')]

messageBox = [message,message1]
chat_model.batch(messageBox)

返回的是一个列表【AIMessage,AIMessage】

9.流式输出

from langchain_core.messages import SystemMessage,HumanMessage,AIMessage
import dotenv
dotenv.load_dotenv()
# 1.获取对话模型
chat_model = ChatOpenAI(
    streaming=True
)
message = [HumanMessage(content='梦幻西游手游好玩嘛')]

# 2.调用对话模型
for chunk in  chat_model.stream(message):
    print(chunk.content,end='',flush=True) #

10.提示词模版

1.LLM提示模版 PromptTemplate

format 和 invoke
format 返回的是一个字符串 参数给变量赋值
invoke 返回 StringPromptValue 参数是字典的方式

from langchain_core.prompts import PromptTemplate
# 创建 实例
#template = PromptTemplate(
#  template='你是一个{role},你的名字叫{name}',
#  input_variables=['role','name']
#)
template = PromptTemplate.from_template(
    template='你是一个{role},你的名字叫{name}',
)

#部分提示词模版
# 方式1
# template = PromptTemplate.from_template(
#     template='你是一个{role},你的名字叫{name}',
#     partial_variables={'name':'partial_variables'}
# )
# 方式二
# template = PromptTemplate.from_template(
#     template='你是一个{role},你的名字叫{name}',
# ).partial(name='ddddd')


# 变量赋值
# prompt = template.format(role = '人工智能专家')
prompt = template.invoke(input = {"role" : '人工智能专家'})

2.ChatPromptTemplate

1.实例化方式:1.构造函数 2。from_message()
2.调用提示词模版的方法
1.invoke(),format(),format_message(),format_prompt()
3.更丰富的实例化参数
4.结合LLM 。
5.插入消息列表 MessagePlaceholder

#%% md
# ChatPromptTemplate
1.实例化方式:1.构造函数 2。from_message()
2.调用提示词模版的方法
    1.invoke(),format(),format_message(),format_prompt()
3.更丰富的实例化参数
4.结合LLM 。
5.插入消息列表 MessagePlaceholder
#%%
from langchain.chains.question_answering.map_reduce_prompt import messages
from langchain_core.messages import HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# messages [('角色',内容)]
# 方式一
# chat = ChatPromptTemplate(
#     messages=[
#         ("system",'你是一个ai助手,你的名字叫{name}'),
#         ("human","我的问题是{question}")
#     ],
#     input_variables = ['name','question']
# )

# 方式二
# chat = ChatPromptTemplate(
#     [
#         ("system",'你是一个ai助手,你的名字叫{name}'),
#         ("human","我的问题是{question}")
#     ]
# )

# 方式三 推荐
chat = ChatPromptTemplate.from_messages(
    [
        ("system",'你是一个ai助手,你的名字叫{name}'),
        ("human","我的问题是{question}")
    ]
)




# 方式1 推荐 返回的是一个 ChatPromptValue
# temp = chat.invoke(input={'name':'杨杰','question':'1+1=几'})

# 方式二 format 返回str
# temp = chat.format(name='杨杰',question='1+1=几')

# 方式三 format_messages  返回一个list
# temp = chat.format_messages(name='杨杰',question='1+1=几')

# 方式四 format_messages  返回一个ChatPromptValue
temp = chat.format_prompt(name='杨杰',question='1+1=几')

print(temp,type(temp))

# 将ChatPromptValue 转换为message list
# temp = temp.to_messages() list
# temp = temp.to_string() string

更丰富的实例化参数类型

本质:不管是构造方法还是使用from_message都是传入消息列表,从调用上来讲他们的message参数list中的元素类型是可以多样的

1.字符串类型 。
2.字典类型
3.消息类型
4.元组构成的列表 常用
5.chat提示词模版类型
6.消息提示词模版类型

字符串 默认是human 返回list

messages = [
    '我的问题是{xxx}'
]

字典类型 返回list

messages = [
    {
        'role':'system',
        'content':'我的问题是{xxx}'
    }
]

消息类型 返回list 这里放变量没用 要使用变量使用消息提示词模版

messages = [
    SystemMessage(content='xxxxx')
]

chat提示词模版类型 返回list

mode = ChatPromptTemplate([])
messages = [
    mode
]

消息提示词模版类型 返回list

# 创建消息
sys = "你是一个专家{name}"
system_message = SystemMessagePromptTemplate.from_templatte(sys)

messages = [
    system_message
]

结合LLM使用 + 插入消息列表 MessagesPlaceholder

from  langchain_openai import ChatOpenAI
from langchain_core.prompts import  ChatPromptTemplate
from langchain_core.messages import HumanMessage,AIMessage
import dotenv
from langchain_core.prompts.chat import MessagesPlaceholder


dotenv.load_dotenv()


model = ChatOpenAI()

messages1 = ChatPromptTemplate.from_messages(
    [
        ('system','你是一个ai助手,你的名字叫{name}'),
        # ('human','我的问题是{question}')
        # 不知道角色 可以用 MessagesPlaceholder
        MessagesPlaceholder(variable_name='msg')
    ]
)

# messages = messages1.invoke(input={'name':'yang','question':'1+6=?'})

messages = messages1.invoke(input={
    'name':'yang',
    'msg':[HumanMessage(content='我的问题是:1+1+2=?'),AIMessage(content='1+1+2=5')]
})

res = model.invoke(messages)

print(res)

3.FewShotPromptTemplate: 与PromptTemplate 一起使用

from tkinter.scrolledtext import example

from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from  langchain_openai import ChatOpenAI
import  dotenv
dotenv.load_dotenv()
# 创建 实例

template = PromptTemplate.from_template(
    template='input:{input}\noutput:{output}',
)
# 提供一些示例
examples = [
    {'input':'北京天气怎么样','output':'北京市'},
    {'input':'南京下雨了吗','output':'南京市'},
]
FewS = FewShotPromptTemplate(
    example_prompt=template,
    examples = examples,
    suffix='input:{input}\noutput:', #声明在示例后面的提示词模版
    input_variables= ['input']
)

fff = FewS.invoke({'input':'杭州会下雨吗'})

chat = ChatOpenAI(
    temperature=0.5,
    max_tokens=20,
)

data = chat.invoke(fff)
print(data)

4.FewShotChatMessagePromptTemplate 与ChatPromptTemplate 一起使用

#%% md

#%% md
# 少量示例的提示词模版的使用

FewShotPromptTemplate: 与PromptTemplate 一起使用

FewShotChatMessagePromptTemplate 与ChatPromptTemplate 一起使用


Example seleectors 示例选择器
#%% md
FewShotPromptTemplate的使用
#%%
from tkinter.scrolledtext import example

from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from  langchain_openai import ChatOpenAI
import  dotenv
dotenv.load_dotenv()
# 创建 实例

template = PromptTemplate.from_template(
    template='input:{input}\noutput:{output}',
)
# 提供一些示例
examples = [
    {'input':'北京天气怎么样','output':'北京市'},
    {'input':'南京下雨了吗','output':'南京市'},
]
FewS = FewShotPromptTemplate(
    example_prompt=template,
    examples = examples,
    suffix='input:{input}\noutput:', #声明在示例后面的提示词模版
    input_variables= ['input']
)

fff = FewS.invoke({'input':'杭州会下雨吗'})

chat = ChatOpenAI(
    temperature=0.5,
    max_tokens=20,
)

data = chat.invoke(fff)
print(data)
#%% md
FewShotChatMessagePromptTemplate 与ChatPromptTemplate 一起使用
#%%

from langchain_core.prompts import ChatPromptTemplate,FewShotChatMessagePromptTemplate
import  dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()

# messages [('角色',内容)]

# 提供一些示例
examples = [
    {'input':'2🐦2','output':'4'},
    {'input':'2🐦3','output':'8'},
]

# 定义示例的消息格式提示词模版
exp = ChatPromptTemplate.from_messages([
    ('human','{input}是多少'),
    ('ai','{output}')
])

chatF = FewShotChatMessagePromptTemplate(
    examples = examples,
    example_prompt=exp
)

chat = ChatPromptTemplate.from_messages(
    [
        ("system",'你是一个数学天才'),
        chatF,
        ("human","我的问题是{input}")
    ]
)

nn = ChatOpenAI()
# 示例的顺序很重要
nn.invoke(chat.invoke(input='2🐦6')).content

# print(data.content)


5.PromptTemplate

管道,将一个结果 给到另一个结果 再给到下一个结果

6.自定义模版 BasePromptTemplate

xxxxx

7.持久化 提示词

yaml 或 json文件

prompt.yaml

_type:
  'prompt'
input_variables:
  ['name','what']

prompt.json

{
  "_type": "prompt",
  "input_variables": ["name","what"],
  "template": "请给{name}讲一个{what}的故事"
}

使用

from langchain_core.prompts import  load_prompt
import dotenv

dotenv.load_dotenv()

# prompt = load_prompt('prompt.yaml',encoding='UTF8')
prompt = load_prompt('prompt.json',encoding='UTF8')
prompt.invoke(input={'name':'年轻人','what':'滑稽'})

11.输出解析器

1.str

from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import dotenv


dotenv.load_dotenv()

chat = ChatOpenAI()
template_message = ChatPromptTemplate.from_messages([
    ('system','你是一个靠谱的{role}'),
    ('human','我的问题是{question}')
]).invoke(input={'role':'人工智能专家','question':'人工智能英文怎么说'})

# AIMessage
data  = chat.invoke(template_message)
# print(data,type(data))

# 1.字符串解析
parser = StrOutputParser()
data = parser.invoke(data)
print(data,type(data))

2.json

from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import OpenAI
import dotenv


dotenv.load_dotenv()

chat = OpenAI()
parser = JsonOutputParser()
template_message = PromptTemplate.from_template(
    template = '回答用户的查询\n 满足的格式为{format_ins}\n 问题为{question}\n',
    partial_variables= {'format_ins' : parser.get_format_instructions()}
).invoke(input={'question':'告诉我一个笑话'})

data  = chat.invoke(template_message)
# print(data,type(data))

print(data,type(data))

3.XML解析器

from langchain_core.output_parsers.xml import XMLOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import dotenv

# 加载环境变量(包含OpenAI API密钥)
dotenv.load_dotenv()

# 初始化模型
llm = ChatOpenAI()

# 创建XML解析器
parser1 = XMLOutputParser()

# 创建提示模板,指定输出格式
template = """
问题:{question}
使用格式:{format_instructions}
"""

prompt = PromptTemplate(
    template=template,
    input_variables=["question"],
    partial_variables={"format_instructions": parser1.get_format_instructions()}
)

# 创建处理链:提示模板 -> 模型 -> 解析器  加上parser1后返回一个字典
chain = prompt | llm | parser1
result = chain.invoke(input={"question": "生成成龙简短的电影记录,使用中文回复"})
print(result)

12.Ollama 本地运行大模型的集成框架

https://www.bilibili.com/video/BV1ZppNzHEY4?spm_id_from=333.788.videopod.episodes&vd_source=2f295d79f6aef9aa782b01873c3964c5&p=39

13.chains将多个组件 串联 形成可复用的工作流

from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import dotenv


dotenv.load_dotenv()

chat = ChatOpenAI()
template_message = ChatPromptTemplate.from_messages([
    ('system','你是一个靠谱的{role}'),
    ('human','我的问题是{question}')
])

parser = StrOutputParser()
# template_message.invoke()
#chat.invoke(template_message.invoke())
#paarser.innvoke(chat.invoke(template_message.invoke()))
chain = template_message | chat | parser
result = chain.invoke(input={'role':'人工智能专家','question':'人工智能英文怎么说,问题用q表示,答案用a表示'})

print(result)

1.LLMChian

1.基础链

import dotenv
from langchain.chains.llm import LLMChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

llm = ChatOpenAI()

# 提示词模版
template_pro = ChatPromptTemplate.from_messages(
   [
       ('system','你是一个数学高手'),
       ('human','帮我解决如下的数学问题{question}')
   ]
)

#verbose 详细执行过程
chain = LLMChain(llm=llm,prompt=template_pro,verbose=True)
res = chain.invoke(input={'question':'1+1+2+3 = ?'})

print(res)

2.顺序链 SimpleSequentialChain

第一个输出结果 就是第二个输入的值

import dotenv
from langchain.chains.llm import LLMChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from  langchain.chains.sequential import SimpleSequentialChain

dotenv.load_dotenv()

llm = ChatOpenAI()

# 提示词模版
template_pro = ChatPromptTemplate.from_messages(
   [
       ('system','你是一位梦幻西游手游的玩家'),
       ('human','帮我解决如下的梦幻西游手游的问题{question}')
   ]
)

#verbose 详细执行过程
chain_a = LLMChain(llm=llm,prompt=template_pro,verbose=True)

# 提示词模版
template_pro1 = ChatPromptTemplate.from_messages(
   [
       ('system','你非常善于总结'),
       ('human','针对一个提问的完整回答:{kno}'),
       ('human','根据上述回答概括下20字以内')
   ]
)

#verbose 详细执行过程
chain_b = LLMChain(llm=llm,prompt=template_pro1,verbose=True)

final_chain = SimpleSequentialChain(
    chains=[chain_a,chain_a],
    verbose=True
)


res = final_chain.invoke({'input':'现在玩梦幻西游手游去哪里可以下载?'})

print(res)

3.顺序链SequentialChain

import dotenv
from langchain.chains.llm import LLMChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.chains.sequential import SimpleSequentialChain, SequentialChain

dotenv.load_dotenv()

llm = ChatOpenAI()

# 提示词模版
template_pro = ChatPromptTemplate.from_messages(
   [
       ('system','你是一位各个领域的知名教授'),
       ('human','帮我解决如下的梦幻西游手游的问题{question},并且{action}')
   ]
)

#verbose 详细执行过程
chain_a = LLMChain(
    llm=llm,
    prompt=template_pro,
    verbose=True,
    output_key='chain_aa_key'
)

# 提示词模版
template_pro1 = ChatPromptTemplate.from_messages(
   [
   # 这里也可以使用question/action 作为变量
       ('system','你非常善于总结'),
       ('human','针对一个提问的完整回答:{chain_aa_key}'),
       ('human','根据上述回答概括下20字以内')
   ]
)

#verbose 详细执行过程
chain_b = LLMChain(
    llm=llm,
    prompt=template_pro1,
    verbose=True,
    output_key='chain_b_key'
)

# 一定要声明出两个变量
final_chain = SequentialChain(
    chains=[chain_a,chain_b],
    input_variables=['question','action'],
    output_variables=['chain_aa_key','chain_b_key'],  # 都输出 a 跟 b的结果
    verbose=True
)


res = final_chain.invoke({'question':'现在玩梦幻西游手游去哪里可以下载?','action':'地址给我发出来'})

print(res['chain_b_key'])

4.数学链 解决数学问题

5.路由链

6.文档链

7.creaate_sql_query_chain 新chain

在这里插入图片描述

8.create_stuff_documents_chain

将多个文档内容合并成一个长文本

14.Memory 记忆模式

1.InMemoryChatMessageHistory 基础存储 只存储一个列表

import dotenv
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()
llm = ChatOpenAI()
# 内存中的容器
history  = InMemoryChatMessageHistory()

# 添加消息存储
history.add_user_message('你好')
# history.add_message('系统消息')
history.add_ai_message('很高兴认识你')

history.add_user_message('1+2=?')


data = llm.invoke(history.messages)
print(data.content)


2.ConversationBufferMemory

记录完整对话记录 里面把包含 PromptTemplate ChatPromptTemplate

import dotenv
from langchain.memory.buffer import ConversationBufferMemory
from langchain_openai import ChatOpenAI
from  langchain_core.prompts import PromptTemplate,ChatPromptTemplate,MessagesPlaceholder
from langchain.chains.llm import LLMChain

dotenv.load_dotenv()
llm = ChatOpenAI()
# 内存中的容器 return_messagesTrue 返回的是list False 是返回字符串
memory  = ConversationBufferMemory(return_messages=True)
# memory  = ConversationBufferMemory(return_messages=True,memory_key='xxxx') #这个xxxx对应下面模版xxxx的位置,默认是history
#
# # 添加消息存储 input = human  output = ai
# memory.save_context(inputs={'input':'你好,我叫小明'},outputs={'output':'很高兴认识您'})
# memory.save_context(inputs={'human':'帮我计算一下1+2+3=?'},outputs={'ai':'6'})
#
# print(memory.load_memory_variables({}))
#
# # 返回的字典结构的key叫history
#
# print(memory.chat_memory.message) # 这个是直接打印出history的值




# 结合提示词模版
# prompt_template = PromptTemplate.from_template(
#     template="""
#         你可以与人类对话啊,\n当前的对话啊历史:{xxxx},\n人类的问题是:{question}
#     """
# )



prompt_template = ChatPromptTemplate.from_messages([
    ('system','你是一个与人类对话的机器人'),
    MessagesPlaceholder(variable_name='history'),
    ('human','问题:{question}')
])

chain = LLMChain(llm=llm,prompt=prompt_template,memory=memory)
# data = chain.invoke({'question':'你好,我的名字叫小明'})
# print(data) # 这里第一次打印 history 空的  执行完后存储
# data = chain.invoke({'question':'我叫什么名字呢'})
# print(data)

data = chain.invoke({'question':'中国的首都在哪里'})
print(data) # 这里第一次打印 history 里面就已经放进去值了  执行过程中存储
data = chain.invoke({'question':'我刚刚问了什么'})
print(data)




3.ConversationChain 也是完整存储记录

import dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

dotenv.load_dotenv()
llm = ChatOpenAI()
# prompt_template = PromptTemplate.from_template(
#     template="""
#         你可以与人类对话啊,\n当前的对话啊历史:{history},\n人类的问题是:{input}
#     """
# )

# 创建 ConversationChain 内部提供六默认的提示词模版 变量为input 和 histtory
chain = ConversationChain(llm=llm)
# chain = ConversationChain(llm=llm,prompt=prompt_template)
data = chain.invoke({'input':'你好,我的名字叫小明'})
print(data)
data = chain.invoke({'input':'我的名字叫什么'})
print(data)



4.ConversationBufferWindowMemory 返回最近的几条

记录只存最近k条记录 跟ConversationBufferMemory 用法一样

memory = ConversationBufferWindowMemory(k=2) #只取最近的几条记录

  import dotenv
from langchain.memory import ConversationBufferWindowMemory
from langchain_openai import ChatOpenAI
from  langchain_core.prompts import PromptTemplate,ChatPromptTemplate,MessagesPlaceholder
from langchain.chains.llm import LLMChain

dotenv.load_dotenv()
llm = ChatOpenAI()
# 内存中的容器 return_messagesTrue 返回的是list False 是返回字符串
memory  = ConversationBufferWindowMemory(k=2) #只取最近的几条记录
# memory  = ConversationBufferWindowMemory(return_messages=True,memory_key='xxxx') #这个xxxx对应下面模版xxxx的位置,默认是history

# 添加消息存储 input = human  output = ai
memory.save_context(inputs={'input':'你好'},outputs={'output':'怎么了'})
memory.save_context(inputs={'input':'你是谁'},outputs={'output':'我是ai助手'})
memory.save_context(inputs={'human':'帮我计算一下1+2+3=?'},outputs={'ai':'6'})

print(memory.load_memory_variables({}))
prompt_template = PromptTemplate.from_template(
    template="""
        你可以与人类对话啊,\n当前的对话啊历史:{history},\n人类的问题是:{question}
    """
)
chain = LLMChain(llm=llm,prompt=prompt_template,memory=memory)
data = chain.invoke({'question':'你好,我的名字叫小明'})
print(data) # 这里第一次打印 history 空的  执行完后存储
data = chain.invoke({'question':'我叫什么名字呢'})
print(data)


5.ConversationTokenBufferMemory 根据token保存记录

import dotenv
from langchain_openai import ChatOpenAI
from  langchain_core.prompts import PromptTemplate,ChatPromptTemplate,MessagesPlaceholder
from langchain.chains.llm import LLMChain
from langchain.memory.token_buffer import  ConversationTokenBufferMemory


dotenv.load_dotenv()

llm = ChatOpenAI()


memory = ConversationTokenBufferMemory(
    llm = llm,
    max_token_limit= 20 # 设置token的数量
)

memory.save_context({'input':'你好吗'},{'output':'很好谢谢'})
memory.save_context({'input':'今天天气如何'},{'output':'晴天25度'})

print(memory.load_memory_variables({}))

6.ConversationSummaryMemory 返回过去k条的简介摘要

如果实例化ConversationSummaryMemory前没有历史消息 可以使用构造函数

import dotenv
from langchain_openai import ChatOpenAI
from langchain.memory import  ConversationSummaryMemory


dotenv.load_dotenv()

llm = ChatOpenAI()


memory = ConversationSummaryMemory(
    llm = llm,
)

memory.save_context({'input':'你好吗'},{'output':'很好谢谢'})
memory.save_context({'input':'今天天气如何'},{'output':'晴天25度'})

print(memory.load_memory_variables({}))


import dotenv
from langchain_openai import ChatOpenAI
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain.memory import  ConversationSummaryMemory


dotenv.load_dotenv()

llm = ChatOpenAI()


memory = InMemoryChatMessageHistory()

memory.add_user_message('你好吗')
memory.add_user_message('很好谢谢')
memory.add_user_message('今天天气如何')
memory.add_user_message('晴天25度')

memory_o = ConversationSummaryMemory.from_messages(llm=llm,chat_memory=memory)
memory_o.save_context({'input':'你好吗'},{'output':'很好谢谢'})
# memory.save_context({'input':'今天天气如何'},{'output':'晴天25度'})

print(memory_o.load_memory_variables({}))


7.ConversationSummaryBufferMemory 保留最近的记录,早起的以摘要的方案

#保留最近的记录,早起的以摘要的方案
import dotenv
from langchain_openai import ChatOpenAI
from langchain.memory import  ConversationSummaryBufferMemory


dotenv.load_dotenv()

llm = ChatOpenAI()


memory = ConversationSummaryBufferMemory(
    llm = llm,
    max_token_limit=40, # 控制缓存区的大小
    return_messages=True
)

memory.save_context({'input':'你好吗'},{'output':'很好谢谢'})
memory.save_context({'input':'今天天气如何'},{'output':'晴天25度'})

print(memory.load_memory_variables({}))

print(memory.chat_memory.messages)

8.ConversationEntityMemory 了解

基于实体的对话记忆机制,能够智能识别,存储,利用, 例如人名,地点,产品, 例如医疗行业等要用

9.ConversationKGMemory 了解

知识图谱,不光能提取实体,还能提取他们之前的关系

10.向量存储 持久化 VectorStoreRetrieverMemory 了解

15.客服的例子

#保留最近的记录,早起的以摘要的方案
import dotenv
from langchain_openai import ChatOpenAI
from langchain.memory import  ConversationSummaryBufferMemory
from langchain_core.prompts.chat import  MessagesPlaceholder
from langchain.chains.llm import LLMChain

dotenv.load_dotenv()

llm = ChatOpenAI()

# 模版
prompt = ChatPromptTemplate.from_messages(
    [
        ('system','你是一个电商服务助手,用中文友好的回复用户问题,保持专业但亲切的语气'),
        MessagesPlaceholder(variable_name='history'),
        ('human','{input}')
    ]
)

# 创建带摘要的缓存记忆系统
memory = ConversationSummaryBufferMemory(
    llm = llm,
    max_token_limit=400, # 控制缓存区的大小
    memory_key='history',
    return_messages=True
)

# 创建对话链
chain = LLMChain(
    llm=llm,
    prompt=prompt,
    memory=memory
)

# 模拟多伦对话
dialogue = [
    ('你好,我想查询订单12345的状态',None),
    ('这个订单是上周五下的',None),
    ('我现在急着用,能加急处理吗',None),
    ('等等,我可能记错订单号了,应该是12346',None),
    ('对了,你们退货政策是怎么样的 ',None),
]

# 执行对话
for item,_ in dialogue:
    print(item)
    res = chain.invoke({'input':item})
    print(f'用户:{item}')
    print(f'客服:{res["text"]}')


# 查看当前的记忆状态
print('\n------------')

print(memory.load_memory_variables({}))

16.tools 大模型工具

1.两种定义方式

from pydantic import BaseModel, Field
from debugpy.launcher.debuggee import describe
from langchain_core.tools import tool, StructuredTool


class FieldInfo(BaseModel):
    a:int = Field(description = '第一个参数')
    b:int = Field(description = '第二个参数')

@tool(
    name_or_callable='add', # 名字
    description='add two he',
    return_direct=True,# 是否直接返回
    args_schema=FieldInfo #参数描述
)
def add_number(a:int,b:int)->int:
    """计算两个数之和"""
    return a+ b



print(add_number.name) #默认是函数的名称
print(add_number.args)
print(add_number.description) #  """计算两个数之和""" 也可以设置 description
print(add_number.return_direct) #默认值False

res = add_number.invoke({'a':1, 'b':2})
print(res)

from  langchain_core.tools.structured import  StructuredTool
from pydantic import BaseModel, Field
def search_google(query:str)->str:
    return '最后查询结果'

class FieldInfo(BaseModel):
    query:int = Field(description = '第一个参数')

search1 = StructuredTool.from_function(
    func=search_google,
    name='搜索',
    description='查询谷歌信息的工具',
    args_schema=FieldInfo
)


print(search1.name) #默认是函数的名称
print(search1.args)
print(search1.description) #  """计算两个数之和""" 也可以设置 description
print(search1.return_direct) #默认值False

2.tools模型调用工具

如果大模型分析出抵用对应的工具 content为空 additional_kwargs 包含相应的信息

1.大模型与Agent的区别 :是否涉及到工具的调用

2.针对大模型 仅能分析出调用的工具 不能执行
针对Agent,能分析出调用的工具 并且执行



import dotenv
from langchain_community.tools import MoveFileTool
from langchain_core.messages import HumanMessage
from langchain_core.utils.function_calling import convert_to_openai_function
from langchain_openai import ChatOpenAI
import json

dotenv.load_dotenv()
llm = ChatOpenAI()

# 1.工具列表
tools = [MoveFileTool()]

# 2.因为invoke调用时 需要传入函数的列表 所以要将工具转换为函数
functions = [convert_to_openai_function(t) for t in tools]

# 3.消息列表
messages = [
    HumanMessage(content='将当前目录下的文件a.txt移动到/Users/yangjie/Desktop/python/langchain11/aaa')
]

# 4调用大模型
res = llm.invoke(
    input = messages,
    functions = functions
)

# 5.调用工具
if 'function_call' in res.additional_kwargs:
    tool_name = res.additional_kwargs['function_call']['name']
    tool_arguments = json.loads(res.additional_kwargs['function_call']['arguments'])

    if tool_name == 'move_file':
        data = MoveFileTool().invoke(tool_arguments)
        print('工具执行的结果:',data)

    print('\n调用的工具:',tool_name)
    print('\n调用的工具的参数:',tool_arguments)
else:
    print('模型回复')


print(res)


17.Agent 工具使用

1.使用 AgentType + initialize_agent

1.单工具的使用

方式一

import os

from langchain.agents import AgentType, initialize_agent
from langchain_community.tools import TavilySearchResults
from langchain_core.tools import StructuredTool, Tool
import dotenv
from langchain_openai import ChatOpenAI
from numpy.f2py.crackfortran import verbose

dotenv.load_dotenv()

# 1.获取Tavily 搜索工具实例
search  = TavilySearchResults(max_results = 3) # 最多取3条搜出来的记录

# 2.获取一个搜索工具
# 方式一:
# search_tool = StructuredTool.from_function(
#     func=search.run,
#     name='Search 搜索',
#     description='用于检索互联网消息'
# )

# 方式二 使用tool
# search_tool = Tool(
#     func=search.run,
#     name='Search 搜索',
#     description='用于检索互联网消息'
# )

# 3.获取大语言模型
llm=ChatOpenAI()

# 4.获取Agent实例
agent = AgentType.ZERO_SHOT_REACT_DESCRIPTION


# 5.获取AgentExecutor
agent_executor = initialize_agent(
    # tools=[search_tool],
    tools=[search],  # 可以直接放search
    llm=llm,
    agent=agent,
    verbose = True
)

res = agent_executor.invoke('查询杭州的天气情况,请输出中文表达')

print(res)


2.多工具
import os

from langchain.agents import AgentType, initialize_agent
from langchain_community.tools import TavilySearchResults
from langchain_experimental.utilities.python import PythonREPL
from langchain_core.tools import StructuredTool, Tool
import dotenv
from langchain_openai import ChatOpenAI
from numpy.f2py.crackfortran import verbose

dotenv.load_dotenv()

# 1.获取Tavily 搜索工具实例
search_tool = Tool(
    func=TavilySearchResults(max_results = 3).run,  # 最多取3条搜出来的记录
    name='Search 搜索',
    description='用于检索互联网消息'
)
# 1.1 定义一个计算工具
pyp_repl_tool = Tool(
    func= PythonREPL().run, # langchain 封装的工具类可以进行数学计算
    name='Search 搜索',
    description='用于数学计算'
)

# 3.获取大语言模型
llm=ChatOpenAI()

# 4.获取Agent实例
agent = AgentType.OPENAI_FUNCTIONS


# 5.获取AgentExecutor
agent_executor = initialize_agent(
    tools=[search_tool,pyp_repl_tool],
    llm=llm,
    agent=agent,
    verbose = True
)

res = agent_executor.invoke('比亚迪当前的股价是多少?比去年上涨里百分之几?中文输出')

print(res)

3.自定义函数工具

在这里插入图片描述

2.使用create_tool_calling_agent + AgentExecutor

ReAct模版可以来源于差价 引入的方式
在这里插入图片描述

from langchain.agents import create_react_agent
import os

from langchain_community.tools import TavilySearchResults
from langchain_core.tools import StructuredTool, Tool
import dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts.chat import ChatPromptTemplate
from langchain.agents.tool_calling_agent.base import create_tool_calling_agent
from langchain.agents.agent import  AgentExecutor

dotenv.load_dotenv()

# 1.获取Tavily 搜索工具实例
search  = TavilySearchResults(max_results = 3) # 最多取3条搜出来的记录

# 2.获取一个搜索工具
search_tool = Tool(
    func=search.run,
    name='Search',
    description='用于检索互联网消息'
)

# 3.获取大语言模型
llm=ChatOpenAI()

message = ChatPromptTemplate.from_messages([
    ('system','你是一个乐于助人的ai助手,根据用户的提问,必要时调用Search工具,使用互联网检索数据'),
    ('human','{input}'),
    ('system',"{agent_scratchpad}"), # 必须要要 用与存储 和 传递 Agent的思考过程,避免丢失上下文
    # ('placeholder',"{agent_scratchpad}"), # 必须要要 用与存储 和 传递 Agent的思考过程,避免丢失上下文
])

# 4.获取Agent实例 crea
# agent = AgentType.ZERO_SHOT_REACT_DESCRIPTION
# agent = create_tool_calling_agent(
agent = create_react_agent(
    tools=[search_tool],
    llm=llm,
    prompt = message,
)



# 5.获取AgentExecutor
agent_executor = AgentExecutor(
    tools=[search_tool],
    agent=agent,
    verbose=True
)

res = agent_executor.invoke({'input':'查询杭州的天气情况,请输出中文表达'})

print(res)

18.Agent 嵌入记忆组件

1.方式一:

import os

from langchain.agents import AgentType, initialize_agent, create_tool_calling_agent, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain_community.tools import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import StructuredTool, Tool
import dotenv
from langchain_openai import ChatOpenAI
from numpy.f2py.crackfortran import verbose


dotenv.load_dotenv()

# 1.获取Tavily 搜索工具实例
search  = TavilySearchResults(max_results = 3) # 最多取3条搜出来的记录

# 2.获取一个搜索工具
search_tool = Tool(
    func=search.run,
    name='Search 搜索',
    description='用于检索互联网消息'
)

# 3.获取大语言模型
llm=ChatOpenAI()

# 获取一个记忆的实例
memory = ConversationBufferMemory(
    return_messages=True,
    memory_key='chat_history' # 必须要设置这个值 固定的 提示词模版中已经定里 chat_history
)

# 4.获取Agent实例 两种方式 推荐 OPENAI_FUNCTIONS
agent = AgentType.CONVERSATIONAL_REACT_DESCRIPTION


# 5.获取AgentExecutor
agent_executor = initialize_agent(
    tools=[search_tool],
    llm=llm,
    memory = memory,
    agent=agent,
    # verbose = True
)

res = agent_executor.invoke({'input','查询杭州的天气情况,请输出中文表达'})

print(res)

res = agent_executor.invoke({'input','北京呢'})

print(res)

2.方式二

import os

from langchain.agents import AgentType, initialize_agent, create_tool_calling_agent, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain_community.tools import TavilySearchResults
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import StructuredTool, Tool
import dotenv
from langchain_openai import ChatOpenAI
from numpy.f2py.crackfortran import verbose


dotenv.load_dotenv()

# 1.获取Tavily 搜索工具实例
search  = TavilySearchResults(max_results = 3) # 最多取3条搜出来的记录

# 2.获取一个搜索工具
search_tool = Tool(
    func=search.run,
    name='Search',
    description='用于检索互联网消息'
)

# 3.获取大语言模型
llm=ChatOpenAI()

# 获取一个记忆的实例
memory = ConversationBufferMemory(
    return_messages=True,
    memory_key='chat_history' # 必须要设置这个值 固定的 提示词模版中已经定里 chat_history
)

message = ChatPromptTemplate.from_messages([
    ('system','根据用户的提问,必要时调用Search工具去查询'),
    ('system','{agent_scratchpad}'),
    ('system',"{chat_history}"), # chat_history变量用于记录上下文
    ('human','{input}'),
])

# 4.获取Agent实例
agent = create_tool_calling_agent(
    llm=llm,
    tools=[search_tool],
    prompt = message,
)


# 5.获取AgentExecutor
agent_executor = AgentExecutor(
    tools=[search_tool],
    memory = memory,
    agent=agent,
    verbose = True
)

res = agent_executor.invoke({'input':'查询杭州的天气情况,请输出中文表达'})

print(res)

res = agent_executor.invoke({'input':'北京呢'})

print(res)

19.Retrieval

RAG 长期记忆

1. 文档加载器

1.不同的文档使用不同的加载器
txt 文档:TextLoader
pdf : PyPDFLoader
csv:CSVLoader
json: JSONLoder
html: UnstructuredHTMLLoader
md:UnstructuredMarkdownLoader
文件目录:DirectoryLoader

1.txt加载
from langchain_community.document_loaders import TextLoader

# 文档路径
file_path = "./xxxx.txt"


# 创建一个实例
text_loader = TextLoader(
    file_path=file_path,
    # encoding="utf-8" # 跟文件的存储格式一样
)

# 调用load() 返回一个list
docs = text_loader.load()

print(docs)


2.pdf加载
#%% md
# 1.不同的文档使用不同的加载器

txt 文档:TextLoader

pdf : PyPDFLoader

csv:CSVLoader

json: JSONLoder

html: UnstructuredHTMLLoader

md:UnstructuredMarkdownLoader

文件目录:DirectoryLoader

#%%

#%% md
1,加载txt
#%%
from langchain_community.document_loaders import TextLoader, PyPDFLoader

# 文档路径
file_path = "./xxxx.txt"


# 创建一个实例
text_loader = TextLoader(
    file_path=file_path,
    # encoding="utf-8" # 跟文件的存储格式一样
)

# 调用load() 返回一个list
docs = text_loader.load()

print(docs)
print(docs[0].metadata)
print(docs[0].page_content)
#%% md
2.PDF
#%%
from langchain_community.document_loaders.pdf import  PyPDFLoader

pdf_loader = PyPDFLoader(
    file_path='./0-获取数据字典.pdf'
)


docs = pdf_loader.load()

print(len(docs))
for doc in docs:
    print(doc)
3.csv 文件
from langchain_community.document_loaders import  CSVLoader

csv_loader = CSVLoader(
    file_path='./xxx.csv',
    source_column='author' # author 必须在csv中有对应的咧
)


docs = csv_loader.load()

print(len(docs))
for doc in docs:
    print('\n打印',doc)
4.json文件

安装jq

pip install jq

from langchain_community.document_loaders.json_loader import  JSONLoader

# 方式一
# json = JSONLoader(
#     file_path = "./eidt.json",
#     # jq_schema=".", # . 表示加载所有数据
#     jq_schema=".children[].chi", # . 表示加载children 中每个对象的chi 返回的是个字符串
#     text_content=False # 将加载的json对象转换为json字符串
# )

# 方式二
json = JSONLoader(
    file_path = "./eidt.json",
    jq_schema=".children[]", # . 表示加载children 中每个对象的chi 返回的是个字符串
    content_key='.chi',  # 多个字段  ".chi +'\\n\\n' + .content "
    is_content_key_jq_parsable=True
)


docs = json.load()

print(docs)

for doc in docs:
    print('\n打印',doc)
5.html

在这里插入图片描述
在这里插入图片描述

6.MarkDown文件

在这里插入图片描述

7.文件目录

在这里插入图片描述

20.具体拆分器

官网有挺多
https://python.langchain.com/api_reference/text_splitters/character/langchain_text_splitters.character.CharacterTextSplitter.html

1.CharacterTextSplitter 文档切分器

1.文档切分器可以按照字符串进行切分,也可以按照Document进行切分 str其实就是Document中的page_content

1.按照字符串
split_text(xxxx) 传入字符串 返回一个list[str]
create_document(xxxx) 传入list[str] 返回一个list[Document]
2.按照Document
split_documents(xxxx) 传入list[Document] 返回值 list[Document]

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter


text_loader =  TextLoader(
    file_path='xxxx.txt',
    encoding='utf-8'
)

docs = text_loader.load()

print(docs)

str_text = docs[0].page_content

# 分割器
splitter = CharacterTextSplitter(
    chunk_size=50, #返回块的最大尺寸 推荐separator
    chunk_overlap=5, #相邻两个块之间的重叠数 最大尺寸的10% ~20%左右
    length_function=len, #用于测量给定块字符数的函数,默认len函数
    separator="。", # ''的话 禁用分隔符, 有的话 分隔符优先
    keep_separator=True, # 是否在块中保留分隔符 默认False
    # add_start_index=True, 如果为True 则在元数据中包含块的索引 默认False
    # strip_whitespace=True 如果为True 则从每个文档的开始结束 去除空白字符 默认True
)

#分割文本
texts = splitter.split_text(str_text)

for item in texts:
    print(len(item),'\n')
    print('------------\n')
    print(item)

2.RecursiveCharacterTextSplitter(推荐) 文档切分器常用

  1. 先按separators [‘\n\n’,‘\n’,’ ‘,’'] 分割
    2.chunk块size大于size继续按照_separator 第二个分割,
    3.chunk_overlap合并得块一起合并,a块+b块 <chunk_size 可以合并

3.TokenTextSplitter 根据token

会根据token的数量 兼容自然边界,优先会在自然边界切断(例如。)
也可以用 CharacterTextSplitter.from_tiktoken_encoder()

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import TokenTextSplitter


text_loader =  TextLoader(
    file_path='xxxx.txt',
    encoding='utf-8'
)

docs = text_loader.load()

print(docs)

str_text = [docs[0].page_content]

# 分割器
# 先按 1. separators 分割  2.chunk块size大于size继续按照_separator 第二个分割, 2,chunk_overlap合并得块一起合并,a块+b块 <chunk_size 可以合并
splitter = TokenTextSplitter(
    chunk_size=33, #返回块的最大尺寸 推荐separator
    chunk_overlap=0, #相邻两个块之间的重叠数 最大尺寸的10% ~20%左右
    encoding_name='cl100k_base', # 对应的是openai编码器  将文本转换为token序列
    length_function=len, #用于测量给定块字符数的函数,默认len函数
    # separators="[]", # 默认 ['\n\n','\n',' ','']
    # keep_separator=True, # 是否在块中保留分隔符 默认False
    # add_start_index=True, #如果为True 则在元数据中包含块的索引 默认False
    # strip_whitespace=True 如果为True 则从每个文档的开始结束 去除空白字符 默认True
)

#分割文本
texts = splitter.create_documents(str_text)

for item in texts:
    print('------------\n')
    print(item.page_content)

4. SemanticChunker 嵌入模型分割

from langchain_community.document_loaders import TextLoader
from langchain_experimental.text_splitter import SemanticChunker
from langchain_openai.embeddings import OpenAIEmbeddings
import  dotenv

dotenv.load_dotenv()

# text_loader =  TextLoader(
#     file_path='xxxx.txt',
#     encoding='utf-8'
# )
#
# docs = text_loader.load()

with open('xxxx.txt',encoding='utf-8') as f:
    docs = f.read()

print(docs)

str_text = [docs]

# 获取嵌入模型
embed_model = OpenAIEmbeddings(
    model='text-embedding-3-large',
)

# 分割器
splitter = SemanticChunker(
    embeddings=embed_model,
    breakpoint_threshold_amount=65.0, # 断点阔值数量 余弦距离角大于65 会拆开
    # 断点阔值类型 [
    # percentile=百分位数,  余弦距离 适用常规文本
    # standard_deviation标准差, 适用与语义化变化剧烈的 例如技术wedge
    # interquartile四分位距,    适用长文档 例如书籍
    # gradient梯度            适用于 实验性需求
    # ]
    breakpoint_threshold_type='percentile'
)


#分割文本
texts = splitter.create_documents(str_text)

for item in texts:
    print('------------\n')
    print(item.page_content)

5.HTMLHeaderTextSplitter 分割html(了解)

6.CodeTextSplitte 分割代码 (了解)

7.MarkdownTextSplitte markdown分割(了解)

21.文档句子向量化

使用开源的向量化模型 例如Hugging Face

1.句子向量化

from langchain_openai import OpenAIEmbeddings
import dotenv


dotenv.load_dotenv()



embed_llm = OpenAIEmbeddings(
    model='text-embedding-ada-002' # 不同的嵌入模型
)

text = "nice to meet you !"

embed_query = embed_llm.embed_query(text=text) #返回的是 list[float]


print(len(embed_query))

print(embed_query[:10])





2.文档向量化

from langchain_openai import OpenAIEmbeddings
import dotenv
from langchain_community.document_loaders import  CSVLoader

csv_loader = CSVLoader(
    file_path='./xxx.csv',
    source_column='author' # author 必须在csv中有对应的咧
)
docs = csv_loader.load()

doc = [doc.page_content for doc in docs]

dotenv.load_dotenv()



embed_llm = OpenAIEmbeddings(
    model='text-embedding-ada-002' # 不同的嵌入模型
)

# text = [
#     "nice to meet you !",
#     "meet you too!",
# ]

embed_query = embed_llm.embed_documents(doc) #返回的是list[][float]


print(len(embed_query))

print(embed_query[:10])


22.向量存储 检索。向量数据库

问题:执行报错了 说是chromadb 要安装 ,我mac电脑怎么也装不上,包不兼容

from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter,RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
import dotenv

dotenv.load_dotenv()

# 1.创建一个TextLoader的实例 指定文档加载
loader = TextLoader(
    file_path='xxxx.txt',
    encoding='utf-8'
)

docs = loader.load()

# 2.创建文本拆分
text_spl = RecursiveCharacterTextSplitter(
    chunk_size=30,
    chunk_overlap=5,
    length_function=len, #用于测量给定块字符数的函数,默认len函数
)
doc_spl = text_spl.split_documents(docs)

# print(doc_spl)
#
# for item in doc_spl:
#     print('------------\n')
#     print(item.page_content)

# 3.创建嵌入模型
embed_model = OpenAIEmbeddings(
    model='text-embedding-ada-002'
)


# 4.将文档及嵌入模型传入 chroma相关结构当中,进行数据存储
# 当前数据存储在哪 from_documents 没有显示的指明存储位置的话,则把当前的数据存在内存中缓存起来
# 可以指定存储位置 persist_directory
db = Chroma.from_documents(
    documents=doc_spl,
    embedding=embed_model,
    persist_directory='./chroma-1'
)


# 数据的检索
# 1.相似度的检索
# query = '人工智能的介绍'
# new_doc = db.similarity_search(query,k=3) #表示返回3个最相关文档 默认4
# for i,doc in enumerate(docs,1):
#     print(doc)


# 2. 支持直接对问题的向量来查询
query = '人工智能的介绍'
embedding_vector = embed_model.embed_query(query)
new_doc = db.similarity_search(embedding_vector,k=3) #表示返回3个最相关文档 默认4
for i,doc in enumerate(docs,1):
    print(doc)

# 3.相似性检索,支持元数据中过滤
query = '人工智能的介绍'
new_doc = db.similarity_search(embedding_vector,k=3,filter={'source','动物'}) #表示返回3个最相关文档 默认4
for i,doc in enumerate(docs,1):
    print(doc)

# 4.通过L2距离的分数进行搜索 L2距离:值越小0 越像
new_doc = db.similarity_search_with_score('人工智能的介绍')
for i,doc in enumerate(docs,1):
    print(doc)

# 5.通过余弦相似度 夹角越接近1 越相似 1 ~ -1
new_doc = db.similarity_search_with_relevance_scores('人工智能的介绍')
for i,doc in enumerate(docs,1):
    print(doc)

# 6.MMR 最大边际相关 0~1 1越相似
new_doc = db.max_marginal_relevance_search(
    query = '人工智能的介绍',
    lambda_mult=0.8
)
for i,doc in enumerate(docs,1):
    print(doc)

23.Retrievers 检索器 应对更复杂的检索场景

在这里插入图片描述

from langchain.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter,RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
import dotenv

dotenv.load_dotenv()

# 1.创建一个TextLoader的实例 指定文档加载
loader = TextLoader(
    file_path='xxxx.txt',
    encoding='utf-8'
)

docs = loader.load()

# 2.创建文本拆分
text_spl = RecursiveCharacterTextSplitter(
    chunk_size=30,
    chunk_overlap=5,
    length_function=len, #用于测量给定块字符数的函数,默认len函数
)
doc_spl = text_spl.split_documents(docs)

# print(doc_spl)
#
# for item in doc_spl:
#     print('------------\n')
#     print(item.page_content)

# 3.创建嵌入模型
embed_model = OpenAIEmbeddings(
    model='text-embedding-ada-002'
)

db = FAISS.from_documents(documents=doc_spl,embedding=embed_model)

# # 基于向量数据库 获取检索器
# retriever = db.as_retriever()
#
# # 进行数据检索
# data = retriever.invoke('人工智能是什么')
#
# for doc in data:
#     print(doc)

# 不同的检索策略
# 1.默认相似度
retriever = db.as_retriever(
    search_kwargs={"k":3}
)
data = retriever.invoke('人工智能是什么')


# 2.分数阈值查询 不会返回得分
retriever = db.as_retriever(
    search_kwargs={"k":3,"score_threshold":0.1},
    search_type='similarity_score_threshold'
)
data = retriever.invoke('人工智能是什么')

# 3.MMR搜索
retriever = db.as_retriever(
    search_kwargs={"k":3,"fetch":2},
    search_type='mmr'
)
data = retriever.invoke('人工智能是什么')

24.结合大模型使用

在这里插入图片描述

在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐