无限可能LangChain——构建代理

news2024/11/28 4:38:13

单独来看,语言模型无法采取行动 - 它们只能输出文本。LangChain的一个重要用例是创建代理。代理是使用LLM作为推理引擎的系统,用于确定要采取的行动以及这些行动的输入应该是什么。然后,这些行动的结果可以反馈给代理,并确定是否需要更多的行动,或者是否可以结束。

在本教程中,我们将构建一个可以与多个不同工具进行交互的代理:一个是本地数据库,另一个是搜索引擎。您将能够向该代理提问,观察它调用工具,并与它进行对话。

概念

我们将涵盖的概念是:

  • 使用语言模型,特别是它们的工具调用能力
  • 创建Retriever以向我们的代理公开特定信息
  • 使用搜索工具在线查找内容
  • 使用LangGraph代理,它使用LLM来思考要做什么,然后执行它
  • 使用LangSmith 调试和跟踪您的应用程序

安装

参考前面文档:

《无限可能LangChain——开启大模型世界》 《无限可能LangChain——构建一个简单的LLM应用程序》

tavily

集成存在于 langchain-community 包中。我们还需要安装 tavily-python 包本身。

pip install -U langchain-community tavily-python langgraph

定义工具

我们首先需要创建我们想要使用的工具。我们将使用两个工具: Tavily(在线搜索),然后是我们将创建的本地索引上的检索器。

Tavily

我们在LangChain中有一个内置工具,可以轻松地使用Tavily搜索引擎作为工具。请注意,这需要一个API密钥。但是如果你没有或者不想创建一个,你可以忽略这一步。

Tavily :https://tavily.com/。创建API密钥后,您需要将其导出为: image.png

export TAVILY_API_KEY="..."
from langchain_community.tools.tavily_search import TavilySearchResults

search = TavilySearchResults(max_results=1)

result = search.invoke("今天重庆的天气预报")
print(result)

image.png

API Reference:TavilySearchResults

Retriever

我们还将在我们自己的一些数据上创建一个检索器。有关此处每个步骤的更深入解释,请参阅 教程。

安装依赖:

pip install faiss-cpu
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

loader = WebBaseLoader("https://help.aliyun.com/zh/dashscope/product-overview/concepts-and-glossary?spm=a2c4g.11186623.0.0.63955491NXmvJ5")
docs = loader.load()
documents = RecursiveCharacterTextSplitter(
    chunk_size=1000, chunk_overlap=200
).split_documents(docs)
vector = FAISS.from_documents(documents, DashScopeEmbeddings())
retriever = vector.as_retriever()

result = retriever.invoke("灵积模型是什么?")
print(result)

API Reference:WebBaseLoader | FAISS | OpenAIEmbeddings | RecursiveCharacterTextSplitter

现在我们已经填充了我们将进行检索的索引,我们可以很容易地将其转换为工具(代理正确使用它所需的格式)

from langchain.tools.retriever import create_retriever_tool

retriever_tool = create_retriever_tool(
    retriever,
    "搜索灵积模型",
    "搜索灵积模型的信息,你可以使用这个工具!",
)

API Reference:create_retriever_tool

工具列表

现在我们已经创建了两者,我们可以创建一个我们将在下游使用的工具列表。

# 创建工具列表
toolList = [search, retriever_tool]

使用语言模型

接下来,让我们通过调用工具来学习如何使用语言模型。LangChain 支持许多不同的语言模型,您可以互换使用-在下面选择您要使用的语言模型!

LangChain 支持内置的 Tavily 工具、支持 DashScopeEmbeddings 工具、支持自定义函数工具。

from langchain_community.tools.tavily_search import TavilySearchResults
search = TavilySearchResults(max_results=1)


from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
loader = WebBaseLoader("https://help.aliyun.com/zh/dashscope/product-overview/concepts-and-glossary?spm=a2c4g.11186623.0.0.63955491NXmvJ5")
docs = loader.load()
documents = RecursiveCharacterTextSplitter(
    chunk_size=1000, chunk_overlap=200
).split_documents(docs)
vector = FAISS.from_documents(documents, DashScopeEmbeddings())
retriever = vector.as_retriever()


from langchain.tools.retriever import create_retriever_tool
retriever_tool = create_retriever_tool(
    retriever,
    "search_dashscope_knowledge",
    "当需要搜索灵积模型相关知识的时候必须使用该工具",
)

from langchain_core.tools import tool
@tool
def multiply(first_int: int, second_int: int) -> int:
    """两个数的乘积."""
    return first_int * second_int


# 创建工具列表
toolList = [search, retriever_tool, multiply]

from langchain_community.chat_models.tongyi import ChatTongyi
llm = ChatTongyi(model="qwen-max")
llm_with_tools = llm.bind_tools([search, retriever_tool, multiply])

# 未使用工具
msg = llm.invoke("你好")
print(msg)

# 建议使用工具:search_dashscope_knowledge
msg = llm_with_tools.invoke("灵积模型是什么")
print(msg)

# 建议使用工具:multiply
msg = llm_with_tools.invoke("计算 10 的 5 倍")
print(msg)

image.png

LangSmith 日志记录: human: 你好 搜索通义千问模型 自定义工具

image.png

这还没有调用那个工具——大模型只是告诉我们建议使用哪个工具。为了真正调用它,下面我们需要创建我们的代理。

创建代理

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

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

# 创建一个代理
agent_executor = create_react_agent(llm, toolList)
msg = agent_executor.invoke(
    {"messages": [HumanMessage(content="你好")]}
)
print(msg)
{'messages': [HumanMessage(content='你好', id='3ef97e5e-e34d-4ca9-81e3-fddee5ecb1a7'), AIMessage(content='你好!有什么可以帮助你的吗?', response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': '5ac46b01-4af0-9c07-bb72-0871767e00a5', 'token_usage': {'input_tokens': 376, 'output_tokens': 7, 'total_tokens': 383}}, id='run-1e3c757e-7b6d-44d2-9979-c38be2a9d7da-0')]}

image.png

为了准确地看到到底发生了什么(并确保它没有调用工具),我们可以看看 LangSmith 跟踪

现在让我们在一个应该调用检索器的示例上尝试一下

# 建议使用工具:search_dashscope_knowledge
msg = agent_executor.invoke(
    {"messages": [HumanMessage(content="灵积模型是什么")]}
)
print(msg)
{'messages': [HumanMessage(content='灵积模型是什么', id='af2612cf-5c10-4c1a-a4ef-b2835e4c135b'), AIMessage(content='', additional_kwargs={'tool_calls': [{'function': {'name': 'search_dashscope_knowledge', 'arguments': '{"query": "灵积模型"}'}, 'id': '', 'type': 'function'}]}, response_metadata={'model_name': 'qwen-max', 'finish_reason': 'tool_calls', 'request_id': '91288216-0c80-9f2e-9e41-b5644cd1adf3', 'token_usage': {'input_tokens': 379, 'output_tokens': 22, 'total_tokens': 401}}, id='run-7430443e-0e55-4a01-87de-47ebda298634-0', tool_calls=[{'name': 'search_dashscope_knowledge', 'args': {'query': '灵积模型'}, 'id': ''}]), ToolMessage(content='什么是DashScope灵积模型服务_模型服务灵积(DashScope)-阿里云帮助中心\n\n\n\n\n\n\n\n\n\n\n\n\n产品解决方案文档与社区权益中心定价云市场合作伙伴支持与服务了解阿里云备案控制台\n文档产品文档输入文档关键字查找\n模型服务灵积\n\n\n\n\n产品概述\n\n\n\n\n\n快速入门\n\n\n\n\n\n操作指南\n\n\n\n\n\n开发参考\n\n\n\n\n\n实践教程\n\n\n\n\n\n服务支持\n\n\n\n首页\n\n\n\n模型服务灵积\n\n\n\n产品概述\n\n反馈上一篇:产品简介下一篇:产品计费 \n文档推荐\n\nDashScope灵积模型服务通过标准化的API提供“模型即服务”(Model-as-a-Service,MaaS)。不同于以往以任务为中心的AI API,DashScope构建在面向未来的、以模型为中心的理念下,因此也引入了一些新的概念和术语。开发者可以通过本文了解DashScope灵积模型服务的有关概念和术语,从而更好的使用DashScope进行AI应用开发。模型和模型服务“模型即服务”是DashScope灵积模型服务的本质:让各种模型的能力触手可得。DashScope将各类AI模型通过标准化的封装形成API服务,以方便应用开发者调用。通过DashScope,丰富多样化的模型不仅能通过推理API被集成,也能通过训练微调API实现模型定制化。DashScope为AI模型提供云原生的Serverless服务,使得开发者无需关注模型服务API背后的服务器管理,也可直接获得稳定可靠的服务。此外DashScope也为有需求的用户提供特定模型的独占服务。在DashScope灵积模型服务中,每个模型都拥有其唯一的模型名称字符串。例如,qwen-turbo\xa0代表的是通义千问大模型、paraformer-v1\xa0代表的是Paraformer语音识别模型等等。模型名称字符串是模型的代号,用于在DashScope API中以指定被调用的模型,通过model=‘模型名称字符串’\xa0给出。API-KEYDashScope灵积模型服务使用API-KEY作为调用API的密钥。API-KEY承担了调用鉴权、计量计费等功能。API-KEY被广泛应用于DashScope API中,通过 api-key\n\nAPI详情\n\n\n安装DashScope SDK\n\n\n快速开始\n\n\n快速开始\n\n\n计量计费\n\n\n模型介绍\n\n\n计量计费规则\n\n\n模型体验中心\n\n\n\n本页导读 (0)\n为什么选择阿里云什么是云计算全球基础设施技术先进稳定可靠安全合规分析师报告产品和定价全部产品免费试用产品动态产品定价价格计算器云上成本管理解决方案技术解决方案文档与社区文档开发者社区天池大赛培训与认证权益中心免费试用高校计划企业扶持计划推荐返现计划支持与服务基础服务企业增值服务迁云服务官网公告健康看板信任中心关注阿里云关注阿里云公众号或下载阿里云APP,关注云资讯,随时随地运维管控云服务联系我们:4008013260法律声明Cookies政策廉正举报安全举报联系我们加入我们友情链接阿里巴巴集团淘宝网天猫全球速卖通阿里巴巴国际交易市场1688阿里妈妈飞猪阿里云计算AliOS万网高德UC友盟优酷钉钉支付宝达摩院淘宝海外阿里云盘饿了么© 2009-2024 Aliyun.com 版权所有 增值电信业务经营许可证: 浙B2-20080101 域名注册服务机构许可: 浙D3-20210002 京D3-20220015浙公网安备 33010602009975号浙B2-20080101-4', name='search_dashscope_knowledge', id='fd5f24e8-7316-44c8-bb53-bcc9ae9c68a3', tool_call_id=''), AIMessage(content='DashScope灵积模型服务是阿里云提供的一种“模型即服务”(Model-as-a-Service,MaaS)解决方案。它允许开发者通过标准化API访问多种AI模型,不仅提供了模型的推理API,还支持模型的训练和微调,以便进行定制化服务。不同于传统以任务为中心的AI API,DashScope更侧重于模型本身,使模型能力更易于获取和集成。\n\n每个模型在DashScope中都有一个唯一的模型名称字符串,作为其标识符,用于在API调用中指定所要使用的模型。例如,`qwen-turbo`代表通义千问大模型,`paraformer-v1`代表Paraformer语音识别模型等。\n\n服务的特点包括:\n- **云原生Serverless**:用户无需管理服务器,即可获得稳定、可靠的服务。\n- **API-KEY鉴权与计费**:通过API-KEY进行调用鉴权和计量计费,简化了开发者在集成AI功能时的权限管理和成本控制流程。\n- **模型多样化**:提供丰富的预训练模型,覆盖多种应用场景,如语言处理、图像识别、语音识别等。\n- **可定制化**:用户可根据特定需求对模型进行微调,以更好地适应个性化场景。\n\n总之,DashScope灵积模型服务旨在降低AI应用的开发门槛,加速AI技术的应用落地,让企业和开发者能够更加便捷地利用先进的AI模型来提升产品和服务的智能化水平。', response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': 'e0b22a7d-91a3-9a10-b0d5-0d2dba07fe2b', 'token_usage': {'input_tokens': 1176, 'output_tokens': 305, 'total_tokens': 1481}}, id='run-52a6b054-4460-494c-8cca-2c6a3e3a6041-0')]}

image.png

让我们来看看 LangSmith跟踪 看看发生了什么。 image.png

现在让我们尝试一个需要调用自定义工具的示例:

# 建议使用工具:multiply
msg = llm_with_tools.invoke("计算 10 的 5 倍等于的结果")
print(msg)
content='' additional_kwargs={'tool_calls': [{'function': {'name': 'multiply', 'arguments': '{"first_int": 10, "second_int": 5}'}, 'id': '', 'type': 'function'}]} response_metadata={'model_name': 'qwen-max', 'finish_reason': 'tool_calls', 'request_id': '7896135e-75e2-93e3-af68-2edb0af85023', 'token_usage': {'input_tokens': 387, 'output_tokens': 25, 'total_tokens': 412}} id='run-987b56a8-5a09-4d68-a217-9bf8459350da-0' tool_calls=[{'name': 'multiply', 'args': {'first_int': 10, 'second_int': 5}, 'id': ''}]

我们可以去看看 LangSmith跟踪 以确保它有效地调用搜索工具。 image.png

流式消息

我们已经看到了如何使用.invoke调用代理以获取最终响应。如果代理正在执行多个步骤,这可能需要一段时间。为了显示中间进度,我们可以在消息发生时流回消息。

for chunk in agent_executor.stream(
    {"messages": [HumanMessage(content="你好")]}
):print(chunk)
print("----")


# 建议使用工具:search_dashscope_knowledge
for chunk in agent_executor.stream(
    {"messages": [HumanMessage(content="灵积模型是什么")]}
):print(chunk)
print("----")


# 建议使用工具:multiply
for chunk in llm_with_tools.stream("计算 10 的 5 倍的结果"):print(chunk)
print("----")
{'agent': {'messages': [AIMessage(content='你好!有什么可以帮助你的吗?', response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': 'f6587cb5-91d9-9abe-a314-2603e821293d', 'token_usage': {'input_tokens': 376, 'output_tokens': 7, 'total_tokens': 383}}, id='run-0ac0c665-226f-4f4e-9c6d-e48db1122731-0')]}}
----
{'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'function': {'name': 'search_dashscope_knowledge', 'arguments': '{"query": "灵积模型"}'}, 'id': '', 'type': 'function'}]}, response_metadata={'model_name': 'qwen-max', 'finish_reason': 'tool_calls', 'request_id': 'e116a070-fc52-9585-8379-8bbac48c92c9', 'token_usage': {'input_tokens': 379, 'output_tokens': 22, 'total_tokens': 401}}, id='run-a0d58c7f-8534-47e5-8208-462ba2cc975c-0', tool_calls=[{'name': 'search_dashscope_knowledge', 'args': {'query': '灵积模型'}, 'id': ''}])]}}
{'tools': {'messages': [ToolMessage(content='什么是DashScope灵积模型服务_模型服务灵积(DashScope)-阿里云帮助中心\n\n\n\n\n\n\n\n\n\n\n\n\n产品解决方案文档与社区权益中心定价云市场合作伙伴支持与服务了解阿里云备案控制台\n文档产品文档输入文档关键字查找\n模型服务灵积\n\n\n\n\n产品概述\n\n\n\n\n\n快速入门\n\n\n\n\n\n操作指南\n\n\n\n\n\n开发参考\n\n\n\n\n\n实践教程\n\n\n\n\n\n服务支持\n\n\n\n首页\n\n\n\n模型服务灵积\n\n\n\n产品概述\n\n反馈上一篇:产品简介下一篇:产品计费 \n文档推荐\n\nDashScope灵积模型服务通过标准化的API提供“模型即服务”(Model-as-a-Service,MaaS)。不同于以往以任务为中心的AI API,DashScope构建在面向未来的、以模型为中心的理念下,因此也引入了一些新的概念和术语。开发者可以通过本文了解DashScope灵积模型服务的有关概念和术语,从而更好的使用DashScope进行AI应用开发。模型和模型服务“模型即服务”是DashScope灵积模型服务的本质:让各种模型的能力触手可得。DashScope将各类AI模型通过标准化的封装形成API服务,以方便应用开发者调用。通过DashScope,丰富多样化的模型不仅能通过推理API被集成,也能通过训练微调API实现模型定制化。DashScope为AI模型提供云原生的Serverless服务,使得开发者无需关注模型服务API背后的服务器管理,也可直接获得稳定可靠的服务。此外DashScope也为有需求的用户提供特定模型的独占服务。在DashScope灵积模型服务中,每个模型都拥有其唯一的模型名称字符串。例如,qwen-turbo\xa0代表的是通义千问大模型、paraformer-v1\xa0代表的是Paraformer语音识别模型等等。模型名称字符串是模型的代号,用于在DashScope API中以指定被调用的模型,通过model=‘模型名称字符串’\xa0给出。API-KEYDashScope灵积模型服务使用API-KEY作为调用API的密钥。API-KEY承担了调用鉴权、计量计费等功能。API-KEY被广泛应用于DashScope API中,通过 api-key\n\nAPI详情\n\n\n安装DashScope SDK\n\n\n快速开始\n\n\n快速开始\n\n\n计量计费\n\n\n模型介绍\n\n\n计量计费规则\n\n\n模型体验中心\n\n\n\n本页导读 (0)\n为什么选择阿里云什么是云计算全球基础设施技术先进稳定可靠安全合规分析师报告产品和定价全部产品免费试用产品动态产品定价价格计算器云上成本管理解决方案技术解决方案文档与社区文档开发者社区天池大赛培训与认证权益中心免费试用高校计划企业扶持计划推荐返现计划支持与服务基础服务企业增值服务迁云服务官网公告健康看板信任中心关注阿里云关注阿里云公众号或下载阿里云APP,关注云资讯,随时随地运维管控云服务联系我们:4008013260法律声明Cookies政策廉正举报安全举报联系我们加入我们友情链接阿里巴巴集团淘宝网天猫全球速卖通阿里巴巴国际交易市场1688阿里妈妈飞猪阿里云计算AliOS万网高德UC友盟优酷钉钉支付宝达摩院淘宝海外阿里云盘饿了么© 2009-2024 Aliyun.com 版权所有 增值电信业务经营许可证: 浙B2-20080101 域名注册服务机构许可: 浙D3-20210002 京D3-20220015浙公网安备 33010602009975号浙B2-20080101-4', name='search_dashscope_knowledge', tool_call_id='')]}}
{'agent': {'messages': [AIMessage(content='DashScope灵积模型服务是阿里云提供的一种“模型即服务”(Model-as-a-Service,MaaS)解决方案。它允许开发者访问和利用多种人工智能模型,而无需直接管理底层基础设施或复杂的模型部署。与传统以任务为中心的AI API不同,DashScope侧重于以模型为中心的方法,使得模型的能力更易于获取和应用。\n\n### 关键特点:\n\n- **模型多样化**: DashScope集成了多种AI模型,涵盖自然语言处理、图像识别、语音识别等多种领域,如通义千问大模型(qwen-turbo)、Paraformer语音识别模型(paraformer-v1)等。\n  \n- **标准化API接口**: 所有模型都通过标准化的API提供服务,便于开发者集成到自己的应用程序中,只需指定模型名称即可调用相应的服务。\n\n- **云原生Serverless服务**: DashScope以Serverless方式提供模型服务,这意味着开发者无需担心服务器管理和运维,即可获得稳定、弹性的模型服务支持。\n\n- **API-KEY鉴权与计费**: 通过API-KEY进行调用鉴权和计量计费,确保服务的安全可控及透明计费。\n\n- **模型定制化能力**: 不仅提供模型推理服务,还支持对特定模型进行训练微调,以满足用户的个性化需求。\n\n- **服务模式灵活**: 提供既有共享模型服务,也有针对特定需求的独占模型服务选项。\n\n总之,DashScope灵积模型服务降低了企业和开发者应用先进AI技术的门槛,使其能够更加聚焦于业务创新和模型的应用,而非模型的搭建和运维。', response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': '8730206d-bd5f-98f2-a23b-0ef2d3c8e8d0', 'token_usage': {'input_tokens': 1176, 'output_tokens': 334, 'total_tokens': 1510}}, id='run-a4dddf0b-4ad2-416e-a3c8-f79dc953ee63-0')]}}
----
content='' additional_kwargs={'tool_calls': [{'type': 'function', 'function': {'name': 'multiply', 'arguments': ''}, 'id': ''}]} id='run-3eef0407-3cf6-4531-bdc8-9180e0543b50' invalid_tool_calls=[{'name': 'multiply', 'args': '', 'id': '', 'error': None}] tool_call_chunks=[{'name': 'multiply', 'args': '', 'id': '', 'index': 0}]
content='' additional_kwargs={'tool_calls': [{'type': 'function', 'function': {'name': '', 'arguments': '{"first_int": 1'}, 'id': ''}]} id='run-3eef0407-3cf6-4531-bdc8-9180e0543b50' tool_calls=[{'name': '', 'args': {'first_int': 1}, 'id': ''}] tool_call_chunks=[{'name': '', 'args': '{"first_int": 1', 'id': '', 'index': 0}]
content='' additional_kwargs={'tool_calls': [{'type': 'function', 'function': {'name': '', 'arguments': '0, "second_int": 5'}, 'id': ''}]} id='run-3eef0407-3cf6-4531-bdc8-9180e0543b50' invalid_tool_calls=[{'name': '', 'args': '0, "second_int": 5', 'id': '', 'error': None}] tool_call_chunks=[{'name': '', 'args': '0, "second_int": 5', 'id': '', 'index': 0}]
content='' additional_kwargs={'tool_calls': [{'type': 'function', 'function': {'name': '', 'arguments': '}'}, 'id': ''}]} id='run-3eef0407-3cf6-4531-bdc8-9180e0543b50' invalid_tool_calls=[{'name': '', 'args': '}', 'id': '', 'error': None}] tool_call_chunks=[{'name': '', 'args': '}', 'id': '', 'index': 0}]
content='' additional_kwargs={'tool_calls': [{'type': 'function', 'function': {'name': '', 'arguments': ''}, 'id': ''}]} response_metadata={'finish_reason': 'tool_calls', 'request_id': '1b6594da-f866-94fa-83ab-b812a20678b0', 'token_usage': {'input_tokens': 387, 'output_tokens': 25, 'total_tokens': 412}} id='run-3eef0407-3cf6-4531-bdc8-9180e0543b50' invalid_tool_calls=[{'name': '', 'args': '', 'id': '', 'error': None}] tool_call_chunks=[{'name': '', 'args': '', 'id': '', 'index': 0}]
----

https://smith.langchain.com/public/de70d1a5-8f4f-4b7e-b98b-98f20abda3c2/r image.png

https://smith.langchain.com/public/e66cecfe-06fb-447a-91ab-e7ba4a39e668/r image.png

https://smith.langchain.com/public/50d1ab01-b39c-454d-804a-eaacb1bd61d3/r image.png

Streaming tokens

除了流回消息之外,流回令牌也很有用。我们可以使用 .astream_events方法。

此.astream_events方法仅适用于Python 3.11或更高版本。

async def main():
     async for event in agent_executor.astream_events(
        {"messages": [HumanMessage(content="你好")]},version="v1"
    ):
        kind = event["event"]
        if kind == "on_chain_start":
            if (
                event["name"] == "Agent"
            ): 
                print(
                    f"Starting agent: {event['name']} with input: {event['data'].get('input')}"
                )
        elif kind == "on_chain_end":
            if (
                event["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"].content
            if content:
                print(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("--")

import asyncio
if __name__ == "__main__":
    asyncio.run(main())
/opt/homebrew/lib/python3.11/site-packages/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: This API is in beta and may change in the future.
  warn_beta(
你好|!|有什么|可以帮助你的吗?|% 

内存缓存

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

# 创建缓存
from langgraph.checkpoint.sqlite import SqliteSaver
memory = SqliteSaver.from_conn_string(":memory:")


# 创建代理
from langgraph.prebuilt import create_react_agent
from langchain_core.messages import HumanMessage
agent_executor = create_react_agent(llm, toolList, checkpointer=memory)
config = {"configurable": {"thread_id": "abc123"}}
agent_executor = chat_agent_executor.create_tool_calling_executor(
    model, tools, checkpointer=memory
)

config = {"configurable": {"thread_id": "abc123"}}
for chunk in agent_executor.stream(
    {"messages": [HumanMessage(content="你好,我是小明")]},config=config
):print(chunk)
{'agent': {'messages': [AIMessage(content='你好,小明!很高兴能为你服务。有什么可以帮助你的吗?', response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': '9b6a6bc9-0814-990b-8d0e-b57d22accb99', 'token_usage': {'input_tokens': 380, 'output_tokens': 15, 'total_tokens': 395}}, id='run-652cdac8-b1e9-4c9d-9efc-eb0a01bd5d5d-0')]}}
for chunk in agent_executor.stream(
    {"messages": [HumanMessage(content="我的名字是什么?")]},config=config
):print(chunk)
{'agent': {'messages': [AIMessage(content='你的名字是小明。', response_metadata={'model_name': 'qwen-max', 'finish_reason': 'stop', 'request_id': '6643c950-f2f1-960e-a38a-24fcb7557099', 'token_usage': {'input_tokens': 409, 'output_tokens': 6, 'total_tokens': 415}}, id='run-4639c443-a3fb-413a-a294-c8a72ee67df2-0')]}}

运行日志: https://smith.langchain.com/public/2813f856-3042-4ae8-88fd-aea5e3b92931/r https://smith.langchain.com/public/1dba567b-446f-47a9-9133-ded23ea64f38/r

结论

就这样结束了!在这个快速的开始中,我们介绍了如何创建一个简单的代理。然后我们展示了如何流回响应——不仅是中间步骤,还有令牌!我们还添加了内存,这样你就可以和他们对话了。代理是一个复杂的话题,有很多东西要学!

有关代理的更多信息,请查看 LangGraph 文档。这有它自己的一组概念、教程和操作指南。

欢迎关注微信公众号【千练极客】,尽享更多干货文章! qrcode_for_gh_e39063348296_258.jpg

本文由博客一文多发平台 OpenWrite 发布!

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

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

相关文章

探索智慧农业系统架构的设计与应用

随着科技的不断进步和农业现代化的推进,智慧农业正逐渐成为农业发展的重要趋势。智慧农业系统架构的设计与应用,将农业生产与信息技术相结合,为农业生产提供了新的思路和解决方案。本文将深入探讨智慧农业系统架构的设计与应用,从…

【C语言】动态内存经典笔试题(下卷)

前言 如果说动态内存是C语言给我们的一个工具,那么只有掌握了工具的特点我们才能更好地使用。 紧随上卷,我们再来看看动态内存另外两道经典的笔试题。 (建议没看过上卷的朋友可以先看完上卷再回来:【C语言】动态内存经典笔试题…

【MySQL】(基础篇二) —— MySQL初始用

MySQL初始用 目录 MySQL初始用基本语法约定选择数据库查看数据库和表其它的SHOW 在Navicat中,大部分数据库管理相关的操作都可以通过图形界面完成,这个很简单,大家可以自行探索。虽然Navicat等图形化数据库管理工具为操作和管理数据库提供了非…

Kali Linux 2024.2

Kali Linux 2024.2 版本(t64、GNOME 46 和社区包) 比平常晚了一点,但 Kali 2024.2 来了!延迟是由于实现这一目标的幕后变化所致,这也是人们关注的焦点。社区提供了大量帮助,这次他们不仅添加了新的软件包&…

腾讯医疗大模型,不止大模型

“千呼万唤始出来,腾讯健康终于祭出医疗大模型。但或许这只是新故事的开始。下一步通过应用场景的打磨,全面嵌入生态合作伙伴,才能让医疗行业加速全面拥抱「数智化」工具。 在今年几乎所有企业都卷入AI大模型这场豪赌时,腾讯健康…

刘强东的拼搏哲学与产品创新的启示

在当今这个快速变化的时代,成功不再是偶然,而是需要一种敢于挑战、敢于拼搏的精神。正如京东创始人刘强东所说:“实现梦想,记住这句话就够了。敢于挑战,敢于拼搏的人不一定能成功,但成功的人一定是敢于挑战…

04 uboot 编译与调试

新手不需要详细掌握 uboot,只需要知道它是一个什么东西即可,工作中也只是改一些参数而已。 1、uboot 是什么 Linux 系统要启动就必须需要一个 bootloader 程序,也就说芯片上电以后先运行一段 bootloader 程序。这段 bootloader 程序会先初始化 DDR 等外设,然后将 Linux 内…

超详解——python数字和运算——小白篇

目录 1.位运算 2. 常用内置函数/模块 math模块: random模块: decimal模块: 3.内置函数: 总结: 1.位运算 位运算是对整数在内存中的二进制表示进行操作。Python支持以下常见的位运算符: 按位与&…

【最新鸿蒙应用开发】——ArkUI两种开发范式

在进行鸿蒙应用开发,openHarmony提供了一种页面开发框架叫做ArkUI方舟框架来进行页面布局的开发。 ArkUI方舟UI框架 针对不同的应用场景及技术背景,方舟UI框架提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式…

为什么会有虚像

本来我就打算写虚像相关的内容,实际上我看不懂光学的内容,我只是发觉书上没有使用变分法来做,而只是解析几何的变换,这个做法完全脱离实际,物理书为什么会这样写不知道原因,但是很明显这样的内容也非常的复…

基于可解释性深度学习的马铃薯叶病害检测

数据集来自kaggle文章,代码较为简单。 import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)# Input data files are available in the read-only "../input/" directory # For example, runni…

Modbus TCP转CanOpen网关携手FANUC机器人助力新能源汽车

Modbus TCP转CanOpen网关与FANUC机器手臂的现场应用可以实现FANUC机器手臂与其他设备之间的数据交换和通信。CANopen是一种常见的网络协议,用于处理机器和设备之间的通信,并广泛应用于自动化领域。而Modbus TCP是一种基于TCP/IP协议的通信协议&#xff0…

【C++关键字】auto的使用(C++11)

auto的使用(C11) auto关键字auto的使用细则auto使用场景 随着程序的复杂化,程序中用到的类型也越来越复杂化,经常体现在: 1.类型难以拼写 2.含义不明确导致容易出错 在C语言阶段处理这类问题的方法,可以使…

GDPU Java 天码行空15 数据库编程

一、实验目的 1、 了解数据库的基础知识。 2、 掌握MySQL的下载、安装与配置。 3、 掌握MySQL可视化工具的使用。 4、 了解SQL语言。 5、 掌握JDBC中的API,并能进行简单的数据库操作。 二、实验内容 1、 安装MySQL 👨‍🏫 视频教程 2、建…

计算机组成刷题一轮(包过版)

搭配食用 计算机组成原理一轮-CSDN博客 目录 一、计算机系统概述 选择 计算机系统组成 冯诺依曼机 软件和硬件的功能 CPU等概念 计算机系统的工作原理 机器字长 运行速度 求MIPS 编译程序 机器语言程序 平均CPI和CPU执行时间 综合应用 存储程序原理 二…

线性预测器的等价性

摘要 尽管线性模型很简单,但它在时间序列预测中表现良好,即使是在与更深入、更昂贵的模型竞争时也是如此。已经提出了许多线性模型的变体,通常包括某种形式的特征归一化,以提高模型的泛化。本文分析了用这些线性模型体系结构可表…

学生宿舍人走断电系统的开发

学生宿舍人走断电管理系统是一款智能化的电力管理设备,旨在解决学生宿舍用电问题。以下是一些该系统的功能特点: 1.智能控制:系统能够自动识别宿舍内是否有人,当无人时自动断电,避免能源浪费和事故的发生。 2.:系统具有过载保护、短路保护、过…

基于51单片机的串口乒乓球小游戏

基于51单片机的乒乓球小游戏 (仿真+程序) 功能介绍 具体功能: 1.用两块单片机串口进行通信; 2.一排LED模拟乒乓球运动(哪里亮表示运动到哪); 3.当最左边LED亮,表示球…

C 语言实现Linux终端显示IP二维码

调试信息:开发者可以在终端生成二维码,包含调试信息或日志数据,便于移动设备扫描和查看。设备配置:物联网设备配置时,通过终端生成配置二维码,扫描后进行设备配置。 Ubuntu/Debian 环境安装二维码库 sudo a…

以无厚,入有间,做一件事为什么靠努力不行,不能长期维持

庖丁解牛,并不是在说人和技巧,而是在说解牛不在于刀的锋利,而是怎样才能做到让刀不产生损耗,就是熟悉牛肉纹路,按照纹路和肉骨间隙进行操刀。这就是尊重自然规律,对于人也是一样的,如果所有事情…