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 TavilySearchResults

search = 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 ChatOpenAI

model = ChatOpenAI(model="gpt-4")

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

from langchain_core.messages import HumanMessage

response = 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_agent

agent_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"].content
        if 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 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("--")

六、Adding in memory 添加内存

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

from langgraph.checkpoint.sqlite import SqliteSaver

memory = 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("----")

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

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sziitjin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值