Agent:原理与快速构建 | 人工智能 | Langchain | Python ——学习笔记

视频链接:https://www.bilibili.com/video/BV1Hz421b7ag/?spm_id_from=333.788&vd_source=90787f5794c8e73cf358973d1de2e47f

# # 将.env的信息放到环境变量
# from dotenv import load_dotenv
# load_dotenv()''' 第一节课程:使用openai调用智谱轻言问答示例''' 
from openai import OpenAI
client = OpenAI(api_key="你的key",base_url="https://open.bigmodel.cn/api/paas/v4/"
)completion = client.chat.completions.create(model = 'glm-4',        # 使用的模型messages = [            # 对话列表{'role':'system','content':"你被用于抑制用户的购买欲望。当用户说要想买什么东西的时候,你需要提供理由让用户不要买。"},{'role':'user','content':"我正在考虑购买一个键盘,但我想抑制这个购买欲望。你能帮我列出一些理由,让我思考一下是否真的需要这个商品嘛?"}], max_tokens = 400,       # max_tokens用于控制模型输出的长度,取值范围取决于模型和输入,模型有可以处理的token总数,输入和输出不能超过这个数量。像'glm-4'最多token数量为128ktemperature = 0.5       # temperature用于控制输出的随机性,数值越高随机性越大,每次都想得到一样的输出数值可以设置低一点
)print(completion.choices[0].message.content)# # ######################## 以下示例是一个应用完整的调用,主要由3部分组成:Prompt Template、Model、OutputParser######################################
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate# Prompt Template: 用于将Prompt不变的地方固定住,需要变的地方留空。
prompt_template = ChatPromptTemplate.from_messages([('system',"你被用于抑制用户的购买欲望。当用户说要想买什么东西的时候,你需要提供理由让用户不要买。"),('human',"我正在考虑购买一个{product},但我想抑制这个购买欲望。你能帮我列出一些理由,让我思考一下是否真的需要这个商品嘛?")]
)
prompt_template.format(product='球鞋')# Model:用于输入Prompt回答的模型
model = ChatOpenAI(model = 'glm-4',api_key="你的key",base_url="https://open.bigmodel.cn/api/paas/v4/",max_tokens = 500,       # max_tokens用于控制模型输出的长度temperature = 0.7
)# OutputParser:进一步解析模型的输出变成所需要的样子,尤其是输出与需要的不一致时,解析过程可能会再次调用模型
def output_parser(output: str):parser_model = ChatOpenAI(model = 'glm-3-turbo',temperature = 0.2,api_key="你的key",base_url="https://open.bigmodel.cn/api/paas/v4/")message = "你需要将传入的文本改写,尽可能更自然,这是你需要改写的文本:{text}"return parser_model.invoke(message.format(text=output))# 其实在一开始的prompt中就要求回复自然的文本也是可以的。但在工程中,想获取稳定一致的输出,最好一个步骤只做一件事。
chain = prompt_template | model | output_parser     # 这里建立一个完整的调用链
answer = chain.invoke(input={'product':'裤子'})
print(answer.content)# # # # 一个省钱助手 # # #
# chain = prompt_template | model | output_parser     # 这里建立一个完整的调用流程
# while True:
#     product = input("Hello! 马上要双十一,你最近又想买点啥?")
#     answer = chain.invoke(input={'product':product})
#     print(answer.content)''' 第二节课程:langchain添加memory'''
from langchain.prompts import ChatPromptTemplateprompt_template = ChatPromptTemplate.from_messages([('system',"You are a chatbot."),('human',"{new_messages}")]
)print(prompt_template.invoke({'new_messages':'Hello'}).messages)# # # 同样,传入历史消息也是留空一个位置
from langchain.prompts import MessagesPlaceholderprompt_template = ChatPromptTemplate.from_messages([('system',"You are a chatbot."),# ('system', "你是一个聊天机器人"),MessagesPlaceholder(variable_name="chat_history"),('human',"{new_messages}")]
)print(prompt_template.invoke({'chat_history':[('human','Hello'),('ai','Hi'),], 'new_messages':'How old are you?'}).messages)from langchain_openai import ChatOpenAImodel = ChatOpenAI(model = 'glm-3-turbo',api_key="你的key",base_url="https://open.bigmodel.cn/api/paas/v4/",max_tokens = 500,       # max_tokens用于控制模型输出的长度temperature = 0.7
)# # 添加memory步骤:首先用prompt_template和model组成chain,然后定义列表来存储对话记录
chain = prompt_template | model
chat_history = []# 每次调用chain函数时,将传给模型的话和模型返回的话放入chat_history列表,下次调用的时候再作为历史信息传进去
def chat(new_messages):response = chain.invoke({'chat_history': chat_history, 'new_messages': new_messages})chat_history.extend([('human', new_messages),('ai', response.content)])return response.contentprint(chat('你好,我是ysn,今年72岁,已经退休了,正在学习AI知识'))
print(chat('请你阐述一下你了解关于我的个人信息'))# 在实际应用中用langchain的component来实现,对开发一致性和扩展性都更好
from langchain_community.chat_message_histories import ChatMessageHistorychat_history = ChatMessageHistory()chat_history.add_user_message('你好,我是ysn,今年72岁,已经退休正在学习AI知识')
chat_history.add_ai_message('你好,我是AI')from langchain_core.runnables.history import RunnableWithMessageHistorychain_with_memory = RunnableWithMessageHistory(chain,lambda x: chat_history,input_messages_key = 'new_messages',history_messages_key = 'chat_history'
)print(chain_with_memory.invoke({'new_messages': '请你阐述一下你了解关于我的个人信息'}, config={"configurable":{"session_id": "unused"}}).content)
print(chat_history.messages)# 这个函数接受传入chain的东西然后修剪记忆,再将传入chain的东西返回去。
def trim_messages(chain_input):'''修剪记忆'''stored_messages = chat_history.messages# 当大于两条时就清空记忆保留最后两条if len(stored_messages) > 2:chat_history.clear()for message in stored_messages[-2:]:chat_history.add_message(message)return chain_inputchain_with_trimming = trim_messages | chain_with_memoryprint(chain_with_trimming.invoke({'new_messages': '请你阐述一下你了解关于我的个人信息'}, config={"configurable":{"session_id": "unused"}}).content)
print(chat_history.messages)def summarize_messages(chain_input):'''总结记忆,需要调用模型来总结'''stored_messages = chat_history.messages# 当信息数大于等于6条时进行总结if len(stored_messages)>=6:summarization_prompt = ChatPromptTemplate.from_messages([MessagesPlaceholder(variable_name="chat_history"),("user","将上述聊天信息提炼为一条摘要信息。尽可能多的包含具体细节。")])summarization_chain = summarization_prompt | modelsummary_message = summarization_chain.invoke({"chat_history": stored_messages})chat_history.clear()chat_history.add_message(summary_message)return chain_inputchain_with_summarization = summarize_messages | chain_with_memorychat_history.clear()
chat_history.add_message(('human','你好,我是ysn,我今年72岁,已经退休正在学习AI知识'))
chat_history.add_message(('ai','你好,我是AI,请问有什么可以帮你'))
chat_history.add_message(('human','你觉得我适合做AI工程师嘛'))
chat_history.add_message(('ai','适合'))
chat_history.add_message(('human','为什么'))
chat_history.add_message(('ai','因为你在学习AI知识'))print(chain_with_summarization.invoke({'new_messages': '你觉得我适合干什么'}, config={"configurable":{"session_id": "unused"}}).content)
print(chat_history.messages)''' 第三节课程:Agent原理与快速构建'''
# agent 是一种结合了大模型推理能力和实际操作能力的智能体
# 通常我们使用模型是通过问答模式,比如我想实现数据库查询,模型可以告诉我一个Sql语句,然后需要自己粘贴这个语句到数据库中执行,来获取这个查询结果。
#  agent 可以接受我们的自然语言,直接修改数据库,还可以上网查找资料,回答最近发生的事情。# 定义模型
from langchain_openai import ChatOpenAImodel = ChatOpenAI(model = 'glm-4-flash',      # 完全免费且响应速度很快openai_api_base = "https://open.bigmodel.cn/api/paas/v4/",api_key="你的key",
)# 定义 tools    
from langchain_community.tools import DuckDuckGoSearchRun       # DuckDuckGo 搜索引擎免费# 操作数据库的 tool
import pandas as pd
from pandasql import sqldfdef simulate_database_operation(sql):my_table = pd.DataFrame({'name': ['Henry Myers', 'Martha Hawkins', 'Kelsey Lutz', 'Jonathan Fowler', 'Jonathan Young', 'Autumn Johnson', 'Kimberly Macias', 'Jared Mccormick', 'Casey Hoover', 'Erica Morse'],'age': [60, 44, 54, 46, 76, 22, 69, 33, 23, 35],'sex': ['F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M']})result = sqldf(sql)return result
# 正常的查询
print(simulate_database_operation('SELECT * FROM my_table WHERE age > 50'))
# # 错误的查询
# print(simulate_database_operation('SELECT * FROM my_table WHERE id > 50'))# 如何把函数包装成tool? 只要加装饰器和docstring(即使用说明)即可
from langchain.tools import tool@tool   
def simulate_database_operation(sql: str):'''根据sql语句操作数据库'''my_table = pd.DataFrame({'name': ['Henry Myers', 'Martha Hawkins', 'Kelsey Lutz', 'Jonathan Fowler', 'Jonathan Young', 'Autumn Johnson', 'Kimberly Macias', 'Jared Mccormick', 'Casey Hoover', 'Erica Morse'],'age': [60, 44, 54, 46, 76, 22, 69, 33, 23, 35],'sex': ['F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M']})result = sqldf(sql)return result# 模型调用 tool
tools = [DuckDuckGoSearchRun(), simulate_database_operation]
model_with_tools = model.bind_tools(tools)from pprint import pprint as pp# 不需要调用tool的问题
response = model_with_tools.invoke('印度的首都是哪里?')
pp(dict(response))# 不需要调用tool的问题
search_response = model_with_tools.invoke('最近有什么新鲜事?搜索之后告诉我')
pp(dict(search_response))fetch_response = model_with_tools.invoke('现在是北京时间几点?查询之后告诉我')
pp(dict(fetch_response))# 需要操作数据库的问题
db_response = model_with_tools.invoke('帮我往数据库的my_table表中插入一条数据,name是张三,age是18,sex是male')
pp(dict(db_response))######################### 手动实现agent ################################
# from icecream import icdef call_tool(model_output, tools):tools_map = {tool.name.lower(): tool for tool in tools}tools_response = {}for tool in model_output.tool_calls:tool_name = tool['name']tool_args = tool['args']tool_instance = tools_map[tool_name]tool_response = tool_instance.invoke(*tool_args.values())tools_response[tool_name] = tool_responsereturn tools_responsedef manual_agent(query: str, model: ChatOpenAI, tools: list[tool]):'''①模型和工具绑定、②调用绑定的模型查询、③调用tool ④用tool_response和一开始的询问query获取最终的回答final_response'''model_with_tools = model.bind_tools(tools)model_output = model_with_tools.invoke(query)tool_response = call_tool(model_output, tools)final_response = model.invoke(f'original query: {query} \n\n\n tool response: {tool_response}',)return final_responseprint(manual_agent("帮我查询数据库my_table表中有多少人年龄大于60", model, tools).content)# 使用 langgraph 定义 agent
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(model, tools)from langchain_core.messages import HumanMessageresponse = agent.invoke({'messages': [HumanMessage(content="帮我查询数据库my_table表中有多少人年龄大于60")]})
print(response)response = agent.invoke({'messages': [HumanMessage(content="今天在北京的天气怎么样")]})
print(response)

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

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

相关文章

【Kubernetes】常见面试题汇总(十)

目录 29.简述 Kubernetes 自动扩容机制? 30.简述 Kubernetes Service 类型? 31.简述 Kubernetes Service 分发后端的策略? 32.简述 Kubernetes Headless Service ? 29.简述 Kubernetes 自动扩容机制? (…

强化学习——马尔可夫决策过程(MDP)【附 python 代码】

一、马尔可夫过程 过程介绍随机过程在某时刻 t 的状态 S t S_t St​ 通常取决于 t 时刻之前的状态。状态 S t 1 S_{t1} St1​ 的概率表示为: P ( S t 1 ∣ S 1 , . . . , S t ) P(S_{t1}|S_1,...,S_t) P(St1​∣S1​,...,St​)马尔可夫过程某时刻 t 的状态只取…

C++面试模拟01

第一部分:基础知识 问:解释 const 关键字的作用,以及在什么场景下你会使用 const? 问:在 C 中,new 和 malloc 的区别是什么? 问:请解释什么是“深拷贝”和“浅拷贝”?在…

IMS 呼叫流程(详细)

目录 业务模型 典型组网如图1所示 信令流程 具体的语音流程如图2所示 主叫信令面流程 01:UE_A->P-CSCF/ATCF 02:P-CSCF/ATCF_A->PCRF_A 03:PCRF_A->PCSCF/ATCF_A 04:P-CSCF/ATCF_A 处理(把S-CSCF加到Route) 05:S-CSCF_A->MMTel AS/SCC AS_A 06:MM…

JAVA-集合相关

HashMap如何解决哈希冲突的? 计算hash值,基于hashCode计算冲突之后,先是使用链式寻址法当链表长度大于8,且hash表的容量大于60的时候,再添加元素则转化成红黑树 为什么计算hash值是,是将hash地址的值右移1…

JavaSE:13、常用工具类

学习 资源1 学习资源 2 1、数学工具类 import com.test.*;import java.util.Random; import java.util.RandomAccess;public class Main {public static void main(String [] argv) throws Exception {System.out.println(Math.pow(5,3));//125.0System.out.println(Math.a…

大数据Flink(一百一十八):Flink SQL水印操作(Watermark)

文章目录 Flink SQL水印操作(Watermark) 一、为什么要有WaterMark 二、​​​​​​​​​​​​​​Watermark解决的问题 三、​​​​​​​​​​​​​​代码演示 Flink SQL水印操作(Watermark) 一、​​​​​​​为什么…

43.常用C++编译器推荐——《跟老吕学C++》

43.常用C编译器推荐——《跟老吕学C》 常用C编译器推荐一、C编译器介绍1. GCC (GNU Compiler Collection)2. Clang2.1 Clang的特点2.2 Clang的应用场景2.3 Clang与GCC的比较 3. Microsoft Visual C (MSVC)MSVC的特点MSVC的使用场景MSVC与其他编译器的比较 4. Intel C Compiler4…

Spring MVC设置请求头和响应头的Header

在Spring MVC中,动态设置请求头和响应头的方法有多种,以下是一些常见的方式: 设置请求头 使用RequestHeader注解 这个注解用于读取请求中的单个HTTP头部值,并将其作为一个参数传递给控制器方法。 RequestMapping("/examp…

【Midjourney中文版】

Midjourney中文版打破了传统创作工具的界限,无需具备专业的艺术技能或复杂的软件操作能力,即可轻松创作出高质量的图片。它支持多种创作模式,包括文生图、图生图、图片混图融合等,满足多样化的创作需求。 打开Midjourney中文版后…

特斯拉主动巡航技术解析

特斯拉的主动巡航控制技术是其自动驾驶技术套件(Autopilot)中的一项重要功能,旨在提升驾驶的舒适性和便利性。以下是对特斯拉主动巡航技术的详细解析: 一、技术原理与功能 1. 原理概述 特斯拉的主动巡航控制通过车辆前部的摄像…

istio中如何使用serviceentry引入外部服务

假设需要引入一个外部服务,外部服务ip为10.10.102.90,端口为32033. 引入到istio中后,我想通过域名gindemo.test.ch:9090来访问这个服务。 serviceentry yaml内容如下: apiVersion: networking.istio.io/v1beta1 kind: ServiceEn…

【Pycharm】Pycharm创建Django提示pip版本需要升级

目录 1、现象 2、分析 3、本质 前言:经常使用pycharm创建django、flask等项目时候提示pip版本需要升级,解决方案 1、现象 使用Pycharm创建Django项目提示安装Django超时,报错建议pip升级22升级到24 2、分析 之前使用命令升级了pip到了24…

VS code EXPLORER 中不显示指定文件及文件夹设置(如.pyc, __pycache__, .vscode 文件)

VS code EXPLORER 中不显示指定文件及文件夹设置 引言正文方法1打开方式1打开方式2 方法2 引言 VS code 号称地表最强轻量级编译器,其最大的优势在于用户可以根据自己的需求下载适合自己的 extension。从而定制个性化的编译器。然而,本人今天遇到了一个…

出厂非澎湃OS手机解BL锁

脚本作者:酷安mlgmxyysd 脚本项目链接:https://github.com/MlgmXyysd/Xiaomi-HyperOS-BootLoader-Bypass/ 参考 B站作者:蓝空穹 https://www.bilibili.com/read/cv33210124/ 其他参考:云墨清风、水墨青竹、Magisk中文网 决定解BL…

设计模式 组合模式(Composite Pattern)

组合模式简绍 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端可以用一致的方式处理单个对象和组合对象。这样,可以在不知道对象具体类型的条…

通信工程学习:什么是ONT光网络终端

ONT:光网络终端 ONT(Optical Network Terminal,光网络终端)是光纤接入网络(FTTH)中的关键设备,用于将光纤信号转换为电信号或将电信号转换为光信号,以实现用户设备与光纤网络的连接。…

Hive parquet表通过csv文件导入数据

1. background 已建好了 hive parquet 格式的表, 需要从服务器的csv导入数据至该hive表 2. step 提前上传csv至服务器 /path/temp.csv 创建 textfile 格式的中转表(这里使用内部表,方便删除) ,源表名dw_procurement.dwd_tc_comm_plant ,这里中转表加上了csv后缀 CREATE TA…

Koa (下一代web框架) 【Node.js进阶】

koa (中文网) 是基于 Node.js 平台的下一代 web 开发框架,致力于成为应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石; 利用 async 函数 丢弃回调函数,并增强错误处理,koa 没有任何预置的中间件,可快速…

第五部分:2---信号的介绍、产生、处理

目录 信号的概念: 信号表的继承: 信号的分类与编号: 特殊的信号: 信号的产生: 1.键盘输入: 2.系统调用: 3.异常或硬件错误: 4.总结: 信号的处理: …