LangChain-v0.2 Build an Agent 构建代理

语言模型本身不能采取行动,它们只是输出文本。LangChain的一个重要用例是创建代理。代理是使用LLM作为推理引擎来确定要采取哪些行动,以及传递哪些输入的系统。执行操作后,可以将结果反馈到LLM中,以确定是否需要更多操作,或者是否可以完成。

本文我们将构建一个可以与搜索引擎交互的代理。您将能够向该代理提问,观看它调用搜索工具,并与之进行对话。

阅读本文后,你将大致了解以下内容:

1、Tavily 搜索引擎;

2、Using Language Models 使用语言模型;

3、Create the agent 创建代理;

4、Streaming Messages 流式消息;

5、Adding in memory​ 添加内存。

一、Installation​安装

LangChain安装:

pip install -U langchain-community langgraph langchain-anthropic tavily-python

二、使用Tavily 搜索引擎

为了使用它,您需要获取并设置一个 API 密钥:

点击前往:Tavily AI

注册并登录账号,会自动生成一个API Keys

配置TAVILY_API_KEY环境:

import os
os.environ["TAVILY_API_KEY"]="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"

我们首先需要创建我们想要使用的工具。我们选择的主要工具将是 Tavily 搜索引擎。我们在LangChain中有一个内置工具,可以轻松地使用Tavily搜索引擎作为工具。 

from langchain_community.tools.tavily_search import TavilySearchResultssearch = TavilySearchResults(max_results=2)
search_results = search.invoke("深圳天气怎么样?")
print(search_results)
# If we want, we can create other tools.
# Once we have all the tools we want, we can put them in a list that we will reference later.
tools = [search]

三、使用语言模型

LangChain支持许多不同的语言模型,包含:OpenAI、Anthropic、Azure、Google、Cohere、FireworksAI、Groq、MistralAI、TogetherAI等,您可以互换使用 ,选择您要使用的语言模型!

1)下面内容将居于OpenAI语言模型进行演示:

pip install -qU langchain-openai

2)配置API KEY环境

import os
os.environ["OPENAI_API_KEY"]="填写自己的API KEY"
os.environ["LANGCHAIN_TRACING_V2"]="true"
os.environ["LANGCHAIN_API_KEY"]="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"
from langchain_openai import ChatOpenAImodel = ChatOpenAI(model="gpt-4")

3)通过传入消息列表来调用语言模型。默认情况下,响应是一个字符串。

from langchain_core.messages import HumanMessageresponse = model.invoke([HumanMessage(content="hi!")])
response.content

4)现在,我们可以看到启用此模型进行工具调用的感觉。为了实现这一点,我们用来给语言模型提供这些工具的知识;让我们首先用普通消息调用它,看看它是如何响应的。我们既可以看content,也可以看tool_calls。

model_with_tools = model.bind_tools(tools)response = model_with_tools.invoke([HumanMessage(content="Hi!")])print(f"ContentString: {response.content}")
print(f"ToolCalls: {response.tool_calls}")

5)让我们尝试使用一些需要调用工具的输入来调用它。

response = model_with_tools.invoke([HumanMessage(content="What's the weather in Beijin?")])print(f"ContentString: {response.content}")
print(f"ToolCalls: {response.tool_calls}")

我们可以看到现在没有文本内容,但有一个工具调用!它希望我们调用 Tavily Search 工具。这还没有调用该工具,它只是告诉我们可以调用。为了实际调用它,我们需要创建我们的代理。 

四、Create the agent​ 创建代理

现在我们已经定义了工具和 LLM,我们可以创建代理了。我们将使用 LangGraph 来构建代理。
目前,我们正在使用一个高级接口来构建代理,但 LangGraph 的好处是,这个高级接口由一个低级、高度可控的 API 支持,以防你想修改代理逻辑。

1)现在,我们可以使用 LLM 和工具启动代理。请注意,我们传递的是model,而不是model_with_tools。这是因为create_react_agent会在幕后为我们调用.bind_tools。

from langgraph.prebuilt import create_react_agentagent_executor = create_react_agent(model, tools)

现在,我们可以在一些查询上运行代理!请注意,目前,这些都是查询(它不会记住以前的交互)。请注意,代理将在交互结束时返回状态(包括任何输入,我们将在后面看到如何仅获取输出)。

2)首先,让我们看看当不需要调用工具时它是如何响应的:

response = agent_executor.invoke({"messages": [HumanMessage(content="hi!")]})response["messages"]

3)现在让我们看看调用该工具时它是如何响应的:

response = agent_executor.invoke({"messages": [HumanMessage(content="whats the weather in Beijin?")]}
)
response["messages"]

五、Streaming Messages​ 流式消息

我们已经了解了如何调用代理来获得最终响应。如果代理正在执行多个步骤,则可能需要一段时间。为了显示中间进度,我们可以在消息发生时将其流式传输回。

for chunk in agent_executor.stream({"messages": [HumanMessage(content="whats the weather in Beijin?")]}
):print(chunk)print("----")

Streaming tokens 流式tokens

除了流式传输回消息外,流式传输回token也很有用。我们可以用这种方法做到这一点。

async for event in agent_executor.astream_events({"messages": [HumanMessage(content="whats the weather in sf?")]}, version="v1"
):kind = event["event"]if kind == "on_chain_start":if (event["name"] == "Agent"):  # Was assigned when creating the agent with `.with_config({"run_name": "Agent"})`print(f"Starting agent: {event['name']} with input: {event['data'].get('input')}")elif kind == "on_chain_end":if (event["name"] == "Agent"):  # Was assigned when creating the agent with `.with_config({"run_name": "Agent"})`print()print("--")print(f"Done agent: {event['name']} with output: {event['data'].get('output')['output']}")if kind == "on_chat_model_stream":content = event["data"]["chunk"].contentif content:# Empty content in the context of OpenAI means# that the model is asking for a tool to be invoked.# So we only print non-empty contentprint(content, end="|")elif kind == "on_tool_start":print("--")print(f"Starting tool: {event['name']} with inputs: {event['data'].get('input')}")elif kind == "on_tool_end":print(f"Done tool: {event['name']}")print(f"Tool output was: {event['data'].get('output')}")print("--")

六、Adding in memory​ 添加内存

如前所述,此代理是无状态的。这意味着它不记得以前的交互。为了给它内存,我们需要传入一个检查点。传入检查点时,我们还必须在调用代理时传入一个(以便它知道要从哪个线程/对话恢复)。

from langgraph.checkpoint.sqlite import SqliteSavermemory = SqliteSaver.from_conn_string(":memory:")agent_executor = create_react_agent(model, tools, checkpointer=memory)config = {"configurable": {"thread_id": "abc123"}}for chunk in agent_executor.stream({"messages": [HumanMessage(content="hi im bob!")]}, config
):print(chunk)print("----")
for chunk in agent_executor.stream({"messages": [HumanMessage(content="whats my name?")]}, config
):print(chunk)print("----")

如果我想开始一个新的对话,我所要做的就是改变使用过的thread_id

config = {"configurable": {"thread_id": "xyz123"}}
for chunk in agent_executor.stream({"messages": [HumanMessage(content="whats my name?")]}, config
):print(chunk)print("----")

至此,我们介绍了如何创建简单的代理,并展示了如何流式传输响应;我们还添加了内存,以便您可以与他们进行历史记录对话。 

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

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

相关文章

博客前端项目学习day01

这里写自定义目录标题 登录创建项目配置环境变量,方便使用登录页面验证码登陆表单 在VScode上写前端,采用vue3。 登录 创建项目 检查node版本 node -v 创建一个新的项目 npm init vitelatest blog-front-admin 中间会弹出询问是否要安装包&#xff0c…

docker容器重启错误解决方案

目录 起因解决方案重启 起因 是这样的,今天客户服务器的服务器突然断电了,原本是配置了自启动的项目,在重启之后发现还是无法登录,然后又看了一眼工控机,欸,这边居然可以,那么问题就直接排除了…

大样本 OLS 模型及 Stata 具体操作步骤

目录 一、引言 二、理论原理 三、小样本 OLS 和大样本 OLS 的区别 四、数据准备 五、程序代码及解释 六、代码运行结果 一、引言 在统计学和计量经济学中,普通最小二乘法(Ordinary Least Squares,OLS)是一种广泛应用的线性回…

QT-RTSP相机监控视频流

QT-RTSP相机监控视频流 一、演示效果二、关键程序三、下载链接 一、演示效果 二、关键程序 #include "mainwindow.h"#include <QDebug>MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), m_settings("outSmart", "LiveWatcher&…

为什么品牌需要做 IP 形象?

品牌做IP形象的原因有多方面&#xff0c;这些原因共同构成了IP形象在品牌建设中的重要性和价值&#xff0c;主要原因有以下几个方面&#xff1a; 增强品牌识别度与记忆点&#xff1a; IP形象作为品牌的视觉符号&#xff0c;具有独特性和辨识性&#xff0c;能够在消费者心中留…

CSA笔记2-文件管理命令

tree 以树状图显示多级目录 示例&#xff1a; [rootlocalhost ~]# tree haha/ haha/ └── 111 └── 222 2 directories, 0 files [rootlocalhost ~]# tree -L 1 haha/haha/ └── 111 echo > >> < << 示例&#xff1a; [rootxxx ~]#…

【ACM 独立出版,高录用EI稳检索】2024年大数据与数字化管理国际学术会议 (ICBDDM 2024,8月16-18)

2024年大数据与数字化管理国际学术会议 (ICBDDM 2024)&#xff0c;将于2024年8月16-18日在中国上海召开。 “大数据与数字化管理”作为会议主题&#xff0c;旨在聚焦这一跨学科领域中最新的理论研究、技术进展、实践案例和未来趋势。本主题探讨的研究方向涵盖了大数据的收集、…

国家炮制规范-中药饮片炮制规范数据库

2022年12月21日&#xff0c;国家药监局实施了国家药典委员会制定的《国家中药饮片炮制规范》&#xff08;简称《国家炮制规范》&#xff09;&#xff0c;属于中药饮片的国家药品标准&#xff0c;各省需废止与其品名、来源、炮制方法、规格均相同品种的省级中药饮片炮制规范。这…

2024河南萌新联赛第一场 D 小蓝的二进制询问

原题链接&#xff1a;D-小蓝的二进制询问 题意&#xff1a;思路&#xff1a;对于从[l,r]上的数&#xff0c;可以先算出从[0,r]的所有二进制1然后减去[0,l]的所有二进制1。思考如何计算&#xff0c;从样例中给出的5来思考&#xff0c;[0,5]的二进制表示分别为&#xff1a;000&a…

力扣经典题目之->用栈实现队列 的详细讲解与实现,看这篇就够了!

一&#xff1a;题目 二&#xff1a;思路 1&#xff1a;先看两个概念&#xff1a; 2&#xff1a;题目的理解 用两个栈来实现队列&#xff08;表面&#xff09; 用栈的函数来实队列&#xff08;深层&#xff09; 用先进先出的栈函数 来实现后进先出的队列函数 &#xff08;本…

耐玩单机游戏推荐:文明6 电脑游戏分享

《文明VI》呈现融入世界的新方式&#xff1a;城市现已在版图上扩充疆域&#xff0c;积极研究技术和文化可解锁新潜能&#xff0c;而相互竞争的领导者们也将根据其历史特质追寻自己的新议程&#xff0c;而你也将借助五种方式之一取得游戏的胜利。 系统需求 最低配置: 需要 64 …

自动打电话工具开发需要用到的源代码!

随着移动互联网的飞速发展&#xff0c;自动打电话工具的开发需求日益增加&#xff0c;这类工具能够为用户提供便捷的通信体验&#xff0c;节省时间成本&#xff0c;提高生活效率。 然而&#xff0c;要实现自动打电话的功能&#xff0c;并非易事&#xff0c;本文将科普自动打电…

效率飙升!用升级版思维导图搞定测试用例

Xmind思维导图&#xff1c;转&#xff1e;测试用例_如何将xmind改成测试用例-CSDN博客https://weiyv.blog.csdn.net/article/details/135920569 上一次的【xmind思维导图转测试用例】的文章浏览量飙升&#xff0c;这一次把工具又进行升级啦&#xff0c;是在线版的免费工具哦&am…

leetcode日记(42)螺旋矩阵

我使用的是递归&#xff0c;每次递归遍历一圈矩阵&#xff0c;将遍历结果塞进结果vector中&#xff0c;每次遍历修改上下左右边界&#xff0c;直至遍历后其中两边界重合或交错。 class Solution { public:vector<int> spiralOrder(vector<vector<int>>&…

Photoneo 3D 网格划分

Photoneo 3D 网格划分是一种多功能软件解决方案&#xff0c;专为快速、精确的 3D 模型而设计 从多个 3D 扫描或来自 Photoneo 3D 传感器的连续 3D 数据流创建。它 旨在实现适用于各种应用的高级 3D 数据采集&#xff0c;例如 机器人引导、质量检查和逆向工程。 它以两个单独的库…

HarmonyOS 开发者联盟高级认证最新题库

本篇文章包含 Next 版本更新后高级认证题库中95%的题目。 答案正确率 50-60%&#xff0c;答案仅做参考。 请在考试前重点看一遍题目&#xff0c;勿要盲目抄答案。 欢迎在评论留言正确答案和未整理的题目。 1、下面关于方舟字节码格式PREF_IMM16_v8_v8描述正确的是 16位前缀操作…

OSU!题解(概率dp)

题目&#xff1a;OSU! - 洛谷 思路&#xff1a; 设E()表示截止到i所获得的分数&#xff1b; 对于到i点的每一个l&#xff0c;如果第i1点为1&#xff0c;那么会新增分数3*l^23*l1; 就有递推公式方程&#xff1a; E()E()p[i1]p*(3*l^23*l1);(p代表截止到i获得长度l的概率)&a…

C++ :友元类

友元类的概念和使用 (1)将类A声明为B中的friend class后&#xff0c;则A中所有成员函数都成为类B的友元函数了 (2)代码实战&#xff1a;友元类的定义和使用友元类是单向的 (3)友元类是单向的&#xff0c;代码实战验证 互为友元类 (1)2个类可以互为友元类&#xff0c;代码实战…

刷题了:数组理论基础,704. 二分查找,27. 移除元素

学习记录&#xff0c;主要参考&#xff1a;代码随想录 数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合。 数组下标都是从0开始的 数组的元素是不能删的&#xff0c;只能覆盖。 704. 二分查找 要熟悉 根据 左闭右开&#xff0c;左闭右闭 两种区间规则 写出来…

Bubble Cup 13 - Finals [Online Mirror, unrated, Div. 2] --- G. Years (DSmap)

首先会想到树状数组或者差分&#xff0c;但是数据范围为1e9&#xff0c;所以不可取。 那么对于这道题就要用巧妙的方法。 我们可以看到题目也给出了一定的提示&#xff0c;输入的b和d代表了一个人的出生和死亡年份&#xff0c;那么也就是说&#xff0c;假如我们假设出眼前有一…