MRKL 这个词来自一篇论文,它表示的是 Modular Reasoning, Knowledge and Language,可以翻译成模块化推理、知识和语言系统,我们可以把它想成是一种语言模型的用法。LangChain 框架根据篇论文的介绍,设计了一种代理,这种代理可以根据工具的描述来决定要执行的动作。
在这个 Node.js 程序文件里,先导入一个 initializeAgentExecutorWithOptions ,它来自 langchain/agents。下面声明一个 tools,它的值是一组工具,里面添加一个 calculator。
然后声明一个 agentExecutor,等于 await,用一下 initializeAgentExecutorWithOptions 这个函数,初始化一个代理执行器,它需要一组工具,这里就是上面定义的 tools,还需要一个模型,用一下 model,再提供一个对象参数,设置一下要使用的代理的类型,添加一个 agentType 属性,把它的值设置成 zero-shot-react-description,然后可以把 verbose 设置成 true,这样我们可以知道这个代理执行器都干了些什么。
下面声明一个 response,等于 await,用一下 agentExecutor.call 这个方法,提供一个对象参数,里面设置一下 input,它的值是用户的问题,比如 “我现在有10000粉丝,如果每天增加100个粉丝,要达到10万粉丝大概需要多久?”。最后可以输出这个 response 。
在终端,执行一下 node index.mjs。观察一下在控制台上输出的这些东西。这里有一段要交给语言模型处理的 prompt,里面让模型尽最大能力回答用户问题,另外还告模型可以使用的哪些工具。
目前只有一个可用的工具,就是这个 calculator,后面是关于这个工具的一段描述,模型可以根据这段描述来判断在什么情况下可以使用这个工具。
在这段 prompt 里面,还给出了一个格式,比如先是 Question,用户问题,然后是 Thought,这是模型的想法,Action 是要执行的动作,Observation 是观察动作返回的结果,如果说模型返回的 Thought ,是 I now know the final answer,最后会给出最终的答案。
把这段提示交给模型处理,在它返回来的文本里面给出了一段话,说是要计算一下达到10万粉丝需要的天数,要执行的 Action,是 calculator ,Action Input 是动作的输入,这里就是要让 calculator 这个工具计算的一个数学表达式。
代理执行器调用 calculator 计算出来结果以后,会把这个结果作为 Observation ,让模型再观察一下。把这段 prompt 交给模型处理,模型得出的结论是要把这个数字转换成更容易看懂的格式,这里要执行的动作仍然是 calculator,动作的输入是用这个 900/365 ,执行了工具算出了结果以后,再把所有这些信息交给模型继续处理。
最后模型得出了这个问题的答案,说大概需要 3 年时间,粉丝数量可以到 10 万。
总结
通过这个简单的例子,我们大概能够理解 LangChain 框架里的工具、代理还有代理执行器之间的关系。对于 MRKL 这种类型的代理来说,它其实就是一个使用一套特定提示流程的语言模型,它的作用就是根据用户的问题,还有给它提供的一些工具,返回一段关于要做什么事情的描述,还有要执行的具体动作,以及这个动作相关的输入。代理执行器负责执行这个动作,比如执行一个工具,再把工具返回来的结果,带着用户问题,以及之前的一些信息再次交给代理去处理,代理最终会给出问题的答案。