跳过导航
跳过mega-menu

探索LangChain的chat代理

本博客将探讨其中之一 LangChain的代理商:the 带有反应逻辑的聊天代理. 有很多 LangChain 中提到的代理人 LangChain文档但是,我们只关注 反应 代理.

那么什么是 反应 代理按 LangChain文档?

此代理使用 反应 framework to determine which tool to use based solely on the tool’s description. 可以提供任意数量的工具. 此代理要求为每个工具提供描述.

注意:这是最通用的动作剂.

This blog also presents a simple implementation of a chat 代理 using 3 tools that are packaged in LangChain v.0.0.220. 欲知更多有关游乐场代理的详情,请参阅下文.

主要思想

的 带有反应逻辑的聊天代理 可以访问特定的工具列表和大型语言模型(LLM). Upon receiving a user-generated message the chat 代理 asks the LLM which is the best suited tool to answer the question. 它也可能发送最终答案.

它可能会选择一个工具. If this is the case, the question or keywords of it are executed against the tool. 的 tool then returns an output which is then used against the LLM to again plan what to do next: either choose another tool or give the final answer.

So the 代理 uses the LLM for planning what to do next in a loop until it finds the final answer or it gives up.

聊天代理流程

下面是根据聊天代理的流程 LangChain 实现:

聊天代理流程

In a typical scenario of a web or command line application the flow can be divided in two parts:

  • 设置流: used to setup the main parts of the 代理, including the tools and the LLM.
  • 执行流程:由两个循环组成. 的 outer loop processes the 用户输入 and the inner loop processes the 代理 interactions with the tools and the LLM.

理解执行流

的 setup flow is typically just a sequential prelude to the main execution flow:

聊天代理执行流程

该流执行以下步骤:

  • 接受 用户输入. 的 用户输入 is typically a question entered via a web, mobile or command line UI.
  • 代理开始工作:它要求法学硕士使用哪种工具来给出最终答案.
  • 在这个阶段, 第一进程网关 达到. 它有三个输出:
    使用工具法学硕士决定使用一个特定的工具. 在下面的“工具回复”中继续该流程
    给出基于法学硕士的答案法学硕士想出了最后的答案
    回答不明白法学硕士的答案是不确定的. 进程在这里退出,并出现错误.
  • 工具回复:向第二个网关发送消息
  • 第二工作流网关 达到. 它有三种可能的结果:
    —通常情况下,工具的输出被路由到LLM. 我们回到代理循环的初始步骤.
    -如果执行的工具被标记为“返回工具,工具的响应就是最终的答案
    - error condition happens: if the tool throws an error or a timeout occurs or the maximum amount of tries 达到 the process exits with an error.

一个非常简单的维基百科,DuckDuckGo, Arxiv代理

我们已经构建了一个非常简单的代理,它使用了三个内置的 LangChain 代理人:

We have used these three 代理s because they come out of the box in LangChain and also do not require any registration or paid subscriptions.

This command line application can be used to chat about different topics and ask questions like:

  • 唐老鸭是谁??
  • 今天伦敦的天气怎么样?
  • 爱因斯坦是谁??
  • Who will be the presidential candidates for the next presidential election in the US?
  • Which were the most relevant publications about attention layers in neural networks in 2020?

以下是与该工具互动的摘录:

和那个探员玩

我们尝试用颜色编码工具的输出:

  • 绿色:响应成功
  • 红色:错误消息和一些解释
  • blue intermediate step; typically mentioning the tool and the question sent to the tool

实现

我们的聊天应用程序可以在这个GitHub存储库中找到:

GitHub - gilfernandes/代理_playground: 小型演示项目,具有基于LangChain的功能代理.

小型演示项目,具有基于LangChain的功能代理. - GitHub - gilfernandes/代理_playground:小演示…

github.com


主代理代码已输入 代理_playground.py

使用以下代码配置代理:

类配置():
"""
包含LLM的配置.
"""
模型= 'gpt-3.5-turbo-16k”
# model = 'gpt-4'
llm = ChatOpenAI(model=model, temperature=0)

cfg = Config()

我们使用gpt-3.你可以看到5个API.

在下面这个函数中设置代理:

def create_代理_executor(cfg: Config . cfg, action_detector_func:可调用的, verbose: bool = False) -> 代理Executor:
"""
设置代理与三个工具:维基百科,arxiv, duckduckgo搜索
:param cfg LLM的配置.
:param action_detector_func A more flexible implementation of the output parser, 更善于从回应中猜测工具.
:param verbose是否在控制台上有更多输出.
"""
Tools = load_tools(["wikipedia", "arxiv", "ddg-search"], llm=cfg.llm)
代理_executor: 代理Executor = initialize_代理(
工具,
cfg.llm,
代理= 代理Type.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose =详细
)
代理 = 代理_executor.代理
代理.output_parser = ExtendedChatOutputParser(action_detector_func)
返回代理_executor

你可以看到三个工具"维基百科", “arxiv”, and "ddg-search” are loaded here and the 代理 executor is setup here using the CHAT_ZERO_SHOT_REACT_DESCRIPTION类型.

您可能还注意到,我们添加了一个自定义输出解析器. 输出解析器的任务是解析来自LLM的输出. We wanted to have a more flexible implementation of the output parser that could better detect which tool to use — mainly because of a good number of misses we were getting during testing. 这是该工具的实现,可以在文件中找到: chat_output_parser.py.

这是输出解析器的自定义实现:

类ExtendedChatOutputParser (ChatOutputParser):

action_detector_func:可调用的

def __init__(self, action_detector_func:可调用的):
super ().__init__ (action_detector_func = action_detector_func)

def parse(self, text: str) -> Union[代理Action, 代理Finish]:
incles_answer = FINAL_ANSWER_ACTION在文本

试一试:
动作=自我.action_detector_func(文本)
响应= json.负载(行动.带())
incles_action =响应中的"action"
如果包括答案和包括动作:
提高OutputParserException (
"解析LLM输出生成最终答案"
"和一个可解析的动作:{text}"
)
print(get_colored_text(f"Tool: {response['action']}", "blue"))
print(get_colored_text(f"Input: {response['action_input']}", "blue"))
print ()
返回代理Action (
响应“行动”,响应.获取("action_input",{}),文本
)

例外情况如下:
如果没有包括答案:
提高OutputParserException (f"Could not parse LLM output: {text}: {str(e)}")
返回代理Finish (
{“输出”:文本.分割(FINAL_ANSWER_ACTION) [1].带()},文本
)

This implementation allows to specify your custom function for detecting the action — or in other words — which tool to use next.

的 function we wrote to detect the next from the LLM input can be found again in 代理_playground.py:

def action_detector_func(文本):
"""
方法,该方法试图更好地理解LLM的输出.
参数文本:来自LLM响应的文本.
:return a json string with the name of the tool to query next and the input to that tool.
"""
分割=文本.分割(“的”)
if len(splits) > 1:
#原始实现+ json片段删除
返回重新.Sub (r"^json", "",拆分[1])
其他:
Lower_text =文本.低()
Tool_tokens = ["wiki", "arxiv", "duckduckgo"]
Token_tool_mapping = {
“维基”:“维基百科”,
:“arxiv arxiv”,
:“duckduckgo duckduckgo_search”
}
对于tool_tokens中的token:
如果token在lower_text中:
返回json.转储({
“行动”:token_tool_mapping(令牌),
“action_input”:文本
})
提高OutputParserException ('Could not find wiki or arxiv or duckduckgo action nor the final answer.')

在这个函数中, we do not only look for the expected JSON output but also for words which might indicate to use of the next tool.

One of the problems of using LLMs is that they are somehow unpredictable and express themselves in unexpected ways, so this function is just an attempt to capture in a more flexible way the message the LLM wants to convey.

观察

We have noticed that LangChain used a special prompt to query the LLM about the how to react to an input. 这个库中使用的提示符如下:

尽你所能回答以下问题. 您可以使用以下工具:

维基百科:维基百科的包装. 当你需要回答全球最大的博彩平台人的一般性问题时很有用, 的地方, 公司, 事实, 历史事件, 或者其他科目. 输入应该是一个搜索查询.
arxiv: arxiv的包装.当你需要回答有关物理的问题时非常有用, 数学, 计算机科学, 定量生物学, 定量金融学, 统计数据, 电气工程, 和经济学从科学文章在arxiv.org. 输入应该是一个搜索查询.
duckduckgo_search: DuckDuckGo搜索的包装. 当你需要回答有关当前事件的问题时非常有用. 输入应该是一个搜索查询.

使用这些工具的方法是指定一个json blob.
具体地说, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).

的 only values that should be in the "action" field are: 维基百科, arxiv, duckduckgo_search

的 JSON_BLOB美元 should only contain a SINGLE action, do NOT return a list of multiple actions. 下面是一个有效的JSON_BLOB美元的例子:

```
{
“行动”:$ TOOL_NAME
“action_input”:$输入\ n}
```

始终使用以下格式:

问题:您必须回答的输入问题
思想:你应该时刻想着要做什么
行动:
```
JSON_BLOB美元
```
观察:行动的结果
... (这个想法/行动/观察可以重复N次)
心想:我现在知道最后的答案了
最终答案:原始输入问题的最终答案
开始! 提醒你在回复时一定要使用准确的“最终答案”.'

的 prompt is sent via system message to the LLM together with the question or observations from tool responses.

We think it is interesting to know how you instruct the LLM to behave in this scenario.

最终的想法

在这个故事中, we tried to describe how a simple chat 代理 works and tried to understand the inner mechanics of the chat 代理. You can enhance the power of Large Language Models with extra tools which are able to expand the knowledge of LLMs to areas not usually accessible to them. LLMs are not trained on older knowledge base but with openly available information. If you want to access cutting-edge news together with LLMs, 代理s are a good option to start with.

你可以和代理人做更多的事情, 比如让他们参与对抗性场景或代码库, 但我们将在接下来的故事中关注这些场景.

十大正规博彩网站评级

在这里注册