LangChain补充四:Agent知识点和案例补充

news/2024/11/10 15:12:28/文章来源:https://www.cnblogs.com/ssyfj/p/18308247
https://www.alang.ai/langchain/101/lc07

一:基本流程和概念

(一)概念

LangChain Agent的核心思想是,使用大语言模型选择一系列要执行的动作
在Chain中,一系列动作是硬编码在代码中的。
在Agent中,大语言模型被用作推理引擎,以确定要采取的动作及其顺序。
它包括 3 个组件:
  • 规划:将任务分解为较小的子目标
  • 记忆:短期(聊天历史)/ 长期(向量存储)
  • 工具使用:可以利用不同的工具来扩展其功能。

(二)基本流程

工具定义--->定义工具集--->定义prompt--->创建模型实例--->创建Agent(传递进入llm、tools、prompt)--->创建Agent Executor
补充:OpenAI API已弃用functions,而推荐使用tools。两者之间的区别是,tools API允许一次模型请求使用多个函数调用,这可以减少响应时间。

1.工具定义(这里以Serp搜索工具、自定义工具、RAG检索工具为例)

serp搜索需要用到ApiKey,参考https://serpapi.com/manage-api-key
  • Serp搜索
SerpAPI使用案例:
from langchain_community.utilities import SerpAPIWrapper
search = SerpAPIWrapper()
res= search.run("周星驰生日那天是星期几")
print(res)
SerpAPI工具定义:通过第三方api调用内部封装方式(下面就是工具集合)
#三方api
search = SerpAPIWrapper() #搜索引擎
Tool.from_function(func=search.run,name="Search",description="useful for when you need to answer questions about current events" #问一下实时的事情
)
#内部的封装好的
tool = load_tools(["serpapi"])[0]
  • 自定义tool:最常用扩展方式
from datetime import datetime
from langchain_core.tools import tool#函数自定义
@tool("weekday")
def weekday(date_str:str) -> str:"""Convert date to weekday name"""date_object = datetime.strptime(date_str, '%Y-%m-%d')weekday_number = date_object.weekday()weekdays = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日']return weekdays[weekday_number]print(weekday("2024-07-08"))
  • 创建RAG检索工具(里面有调用大模型编码api
RAG使用:
#pip install beautifulsoup4
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddingsheader = {}loader = WebBaseLoader("https://www.cnblogs.com/ssyfj/p/18233391",header_template=header)
docs = loader.load()
documents = RecursiveCharacterTextSplitter(chunk_size=50, chunk_overlap=10
).split_documents(docs)
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
retriever = vector.as_retriever()
print(retriever.invoke("周星驰在2001年拍了什么电影,饰演什么角色"))
添加RAG工具:
from langchain.tools.retriever import create_retriever_toolretriever_tool = create_retriever_tool(retriever=retriever,name="movie_search",description="按电影发布年份搜索关于周星驰的电影,并且查询关于周星驰扮演的角色,对于这种类型的问题,you must use this tool!",
)

2.定义工具集

tools = [searchTool,weekday,retriever_tool]

3.定义prompt

#pip install langchainhub
from langchain import hub
prompt = hub.pull("hwchase17/openai-functions-agent")
[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], template='You are a helpful assistant')),MessagesPlaceholder(variable_name='chat_history', optional=True),HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}')),MessagesPlaceholder(variable_name='agent_scratchpad')
]
注意:这里prompt里面指定了我们传递的变量key是input,如果后续需要传递历史消息,变量是chat_history

4.创建模型实例

from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

5.创建Agent(传递进入llm、tools、prompt):这里以create_openai_tools_agent为例

from langchain.agents import create_openai_tools_agentagent = create_openai_tools_agent(llm, tools, prompt)

6.创建Agent Executor

from langchain.agents import AgentExecutoragent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
#设置 verbose=True,以观察 Agent 调用过程

(三)调用实例

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_community.utilities import SerpAPIWrapper
from langchain.tools.retriever import create_retriever_tool
from langchain_core.tools import tool,Tool
from datetime import datetime
from langchain import hub
from langchain_openai import ChatOpenAI
from langchain.agents import create_openai_tools_agent
from langchain.agents import AgentExecutor
import os#------------工具定义-----------
#1.三方API工具
search = SerpAPIWrapper() #搜索引擎
searchTool = Tool.from_function(func=search.run,name="Search",description="useful for when you need to answer questions about current events" #问一下实时的事情)#2.函数自定义tool
@tool("weekday")
def weekday(date_str:str) -> str:"""Convert date to weekday name"""date_object = datetime.strptime(date_str, '%Y-%m-%d')weekday_number = date_object.weekday()weekdays = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日']return weekdays[weekday_number]#3.RAG检索工具
header = {'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','accept-language': 'zh-CN,zh;q=0.9','cache-control': 'no-cache','cookie': '_ga_M4YHF1JL8J=GS1.2.1689911135.1.1.1689911171.0.0.0; _ga=GA1.1.944087138.1658297907; _ga_7DSFGJNPL4=GS1.1.1690275412.1.0.1690275414.0.0.0; cto_bidid=C83jBV93JTJCSENpcUE3SDVRREJLb3lkMFdXR1d3NTd0ZUdzOUtMUyUyRiUyQkhFa1VXTlllTUZXTmlYeVk3eGpjTW5PWTNhNUhTbHJ0dkp4eCUyRkU2M1pPczNaRG1hNDZ0NGlMcTlHNk4za2hQcHFDWHhQVGFCQUQ3MkZZeDI0WUV6Y2duYzFSWGRJYWE5QUpIWllNcDI4SjVkUDlNQWNxZyUzRCUzRA; __gads=ID=b60ba53f946e1b2e:T=1692005090:RT=1705929053:S=ALNI_MYsgrRdYyIC1T6TS3wkOwjoq1PaPA; __gpi=UID=00000c2c613e3967:T=1692005090:RT=1705929053:S=ALNI_MbXkLNn1vu8qyLrFk19uNuW591dMA; cto_bundle=cAdv_19kJTJCMVR5bCUyQk5WU0E1bHljM0NobkNoeXBjUTVLYXRJTlc2TVdFaVNhY2hXV3o5QXlVTUdNbU5sUUJnaXpwZzh6cXQ5aWxqN1ZybDh4Q01FVnlGM0ZqWmhaRnR1YnFNR092VlFOa2xGUlMzZURaVXF4U1UxWkhOZWRTS2dUUzlpelRPTHRSTGU3MUdOQ2l2dUV1bXNGaUJnJTNEJTNE; .AspNetCore.Antiforgery.b8-pDmTq1XM=CfDJ8C838EyK0EpKpQQcC9VwxBnSb0hM2bTYiKpSxegzCmK7_AE1z_6GOV_tnyqU0cLMIMGsd9Kh8VNURue8BMvp3HTJcCJ5MCandNV3ej4U51Osib__saUI57bcyOn5_l3TXtViuQh1oYWuXHn-fhM6YM4; yjs_id=009fc6ee0de8623a57a53e9e74e83d94; _ga_3Q0DVSGN10=GS1.1.1716353244.10.1.1716353251.53.0.0; Hm_lvt_866c9be12d4a814454792b1fd0fed295=1719232908; .Cnblogs.AspNetCore.Cookies=CfDJ8ONv0caE5GtEh3YJ5j088knFknN6JjsF6H8D1jGHhbTE5YdvkAh-A1xVe03PlKfF4D1UOvChU-6yIAj3dr12_rDR3H1WM8e7_ekJIqaoD41X7qpccR9pde5t9Pnh0Aa6ugNqhZ3X3r0YJxXdxjn4oUb7zUf5-DAro5aKTDPEVc3m6gaySuZ4HRPI_-b9mTXEBD09K7J5qeYT0MzklBXFyV27fcuChdsfvdOky4xGntJ20qc1PV6nmUYOV-BX1AwGgYPjWqY7nUa5UplAhSd1bsYhKDB38TvEIAUeyrrPIfvlqsre3P6QelucFGcR63PrErC_-_maf6rVCkYwHp8UP1gs0X5piJUDVORyWNy98eFLQk0n1ABNuenTGGBDgDRHK4iVNRZN9kR7lJ71vBrOoRBPcmYaLqM-GPrrZ2FcQmKuAqSnU2tVrwxzFaoJryBEc8N2QPX057m8sBW9kRHBxlY710vNQxTa6-qiRMsQxgBULa21EeKh6g855GuP8mtz4TvRQ_Ylg_oknpxEpE8aslvQ6L3ZLyS31dsjeTbIBvEsZG9iM56Uty7YC4TKI8DczwV6zYj-9ijG1EG5X-qDPvOSi4ItHHDJA1zXfThXnpoC; Hm_lpvt_866c9be12d4a814454792b1fd0fed295=1720429794; HMACCOUNT=F60606535C826707; _ga_C2LFP3RFGH=GS1.1.1720429796.26.1.1720429819.0.0.0; _ga_M95P3TTWJZ=GS1.1.1720429795.133.1.1720429819.0.0.0; RT="z=1&dm=cnblogs.com&si=0928aa82-fe37-45da-8ed2-dc749fa2b67e&ss=lycrh8xn&sl=3&tt=2k1&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=lps&ul=zod"','pragma': 'no-cache','priority': 'u=0, i','sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"macOS"','sec-fetch-dest': 'document','sec-fetch-mode': 'navigate','sec-fetch-site': 'none','sec-fetch-user': '?1','upgrade-insecure-requests': '1','user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36',
}loader = WebBaseLoader("https://www.cnblogs.com/ssyfj/p/18233391",header_template=header)
docs = loader.load()
documents = RecursiveCharacterTextSplitter(chunk_size=50, chunk_overlap=10
).split_documents(docs)
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
retriever = vector.as_retriever()
retriever_tool = create_retriever_tool(retriever=retriever,name="movie_search",description="按电影发布年份搜索关于周星驰的电影,并且查询关于周星驰扮演的角色,对于这种类型的问题,you must use this tool!",
)#------------定义工具集-----------
tools = [searchTool,weekday,retriever_tool]#------------定义prompt-----------
prompt = hub.pull("hwchase17/openai-functions-agent")#------------创建模型实例-----------
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)#------------创建Agent-----------
agent = create_openai_tools_agent(llm, tools, prompt)#------------创建Agent Executor-----------
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

1.不需要调用tool

res = agent_executor.invoke({"input": "hi!"})
print(res)

2.调用search工具

res = agent_executor.invoke({"input": "周星驰是谁?"})
print(res)

3.调用search和weekday工具

res = agent_executor.invoke({"input": "周星驰的生日是星期几"})
print(res)

4.调用 RAG 检索工具

res = agent_executor.invoke({"input": "周星驰在2004年主演了什么电影?饰演的角色叫什么?"})
print(res)

二:增加记忆力

class Runnable(Generic[Input, Output], ABC)
/ \|||
class RunnableSerializable(Serializable, Runnable[Input, Output]) 
/ \|||
class Chain(RunnableSerializable[Dict[str, Any], Dict[str, Any]], ABC)
/ \|||class AgentExecutor(Chain)

我们可以看到agent继承chain,两者都是Runnable的子类,可以参考LangChain补充二:LCEL和Runnable更加方便的创建调用链RunnableWithMessageHistory,实现上下文的处理

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistorymessage_history = ChatMessageHistory()
agent_with_chat_history = RunnableWithMessageHistory(agent_executor,lambda session_id: message_history,    #这里没有考虑session_id,对话只维护一个历史input_messages_key="input",history_messages_key="chat_history",    #prompt指定了占位
)agent_with_chat_history.invoke({"input": "周星驰在2004年主演了什么电影"},config={"configurable": {"session_id": "1"}},
)agent_with_chat_history.invoke({"input": "饰演了什么角色呢?"},config={"configurable": {"session_id": "1"}},
)

三:LangChain的代理对比

https://python.langchain.com/v0.1/docs/modules/agents/agent_types/
https://cloud.tencent.com/developer/article/2404258
LLM Completions 已经被标记为 Legacy(不建议使用),所以在实际应用中,建议使用 Chat Model 类型的 Agent 就可以了
代理类型 模型类型 历史对话支持 支持多输入的工具 支持同时调用多工具 使用时机
Tool Calling Chat 使用tool-calling模型时
OpenAI Tools Chat 废弃,tool-calling代替
OpenAI Functions Chat   废弃,tool-calling代替可以并发调用
XML LLM     使用擅长XML的模型时(比如:Anthropic),就可以用到这个agent
Structured Chat Chat   需要支持多输入的工具时
JSON Chat Chat     擅长json的模型,普通chat模型加上prompt即可
ReAct LLM     简单的模型
Self Ask With Search LLM       简单的模型,只有一个搜索工具

补充:Structured Chat 和 JSON Chat 的区别在于对 tool 入参类型的支持上,参数越多,LLM 对工具的学习成本就会越高,Agent 有可能会越不稳定。

Json chat只支持单参数的tool
@tool
def search(query: str) -> str:"""Look up things online."""return "LangChain"
Structured chat支持多参数tool,可以替代json chat
@tool
def multiply(a: int, b: int) -> int:"""Multiply two numbers."""return a * b
Tool calling更🐮,都替代
 

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

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

相关文章

2024-07-17 如何在vscode部署你的代码块,从而在新建页面时能快速搭建模板(windows环境)

步骤一:打开vscode,按住ctrl+shif+p唤出命令窗口 步骤二:在窗口中输入命令,并回车Preferences: Open User Snippets 对,就是这个代码片段,接着输入你想添加代码的某某语言or脚本,比如我要添加vue的代码片段输入vue,回车,会显示vue.json文件出来给你更改,我的是这样 注…

[题解]POJ3675 Telescope——求多边形与圆相交部分的面积

POJ3675 Telescope 题意简述 多测。每次给定一个\(N\)边形(保证相邻输入的顶点在多边形上也是邻接的),再给定一个以\((0,0)\)为圆心,半径为\(r\)的圆。 请计算出多边形和圆相交部分的面积(保留\(2\)位小数)。\(3\le N\le 50\) \(0.1\le r\le 1000\) \(-1000\le x_i,y_i\l…

【专题】2023中国机器人产业分析报告PDF合集分享(附原数据表)

原文链接:https://tecdat.cn/?p=34144 原文出处:拓端数据部落公众号 仿生机器人作为一类结合了仿生学原理的机器人,具备自主决策和规划行动的能力,正逐渐进入大众视野。它们的核心技术要素包括感知与认知技术、运动与控制技术、人机交互技术和自主决策技术。 阅读原文,获…

Splay 学习笔记

Splay 树, 或 伸展树,是一种平衡二叉查找树,它通过 Splay/伸展操作 不断将某个节点旋转到根节点,使得整棵树仍然满足二叉查找树的性质,能够在均摊 O(\log N) 时间内完成插入,查找和删除操作,并且保持平衡而不至于退化为链。 Splay 树由 Daniel Sleator 和 Robert Tarjan …

redis学习-12(实现分布式锁、消息队列、缓存一致性问题、单线程快的原因、跳跃表)

引用以下内容: redis实现分布式锁:Redis分布式锁-这一篇全了解(Redission实现分布式锁完美方案) Redis实现分布式锁的7种方案,及正确使用姿势! redis实现消息队列Redis 的学习教程(十)之使用 Redis 实现消息队列 缓存一致性问题 想要保证数据库和 Redis 缓存一致性,推荐…

数据的运算(上)

逻辑门电路多路选择器和三态门加法器 一位全加器并行进位加法器

idea开发工具配置git,连接到gitee远程仓库

1. 打开idea,Settings里找到如下位置,正常idea会自动找到git,test测试,显示版本号说明正常 2. 创建本地Git仓库,默认就是当前项目路径, 不要修改,直接创建 3. 创建后自动识别出待提交的文件,输入说明,提交,提交后让输入git名称和邮箱,设置并提交,提交成功。我这个项…

使用Apache POI 处理Miscrosoft Office各种格式文件

介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI 都是用于操作 Excel 文件。Apache POI 的应用场景: ● 银行网银系统导出交易明细 ● 各种业务…

闲话 717 - LGV 引理的小应用

717这是我们的某一天的联考题目:\(n\le 500\)。 显然使用平面图完美匹配计数可以获得 \(O(n^6)\),但是有一种神秘的对路径的双射。当时我们都认为这是超级人类智慧,但是今天看书发现是书上的某个例的题的方法(有不同)。。 考虑对正六边形的菱形密铺方案数(上图)。可以等…

useHeadSafe:安全生成HTML头部元素

title: useHeadSafe:安全生成HTML头部元素 date: 2024/7/17 updated: 2024/7/17 author: cmdragon excerpt: 摘要:“useHeadSafe”是Vue.js组合函数,用于安全生成HTML头部元素,通过限制输入值格式避免XSS等安全风险,提供了安全值白名单确保只有安全属性被添加。 categor…

Goby漏洞发布 | CVE-2024-4879 ServiceNowUI /login.do Jelly模板注入漏洞【已复现】

漏洞名称:ServiceNowUI /login.do Jelly模板注入漏洞(CVE-2024-4879) English Name:ServiceNowUI /login.do Input Validation Vulnerability(CVE-2024-4879) CVSS core: 9.3 漏洞描述: ServiceNow 是一个业务转型平台。通过平台上的各个模块,ServiceNow 可用于从人力资…

EMQX配置用户名和密码开启emqx_auth_mnesia认证方式连接

1、 找到MQtt 的 /etc/plugins/ 文件夹下的emqx_auth_mnesia.conf 文件 vim打开编辑该文件,根据例子添加账号密码 并保存 添加内容: auth.user.1.username = admin auth.user.1.password = 123456 2、配置禁止匿名登录(安全认证) 找到emqx.conf编辑## Allow anonymous authe…