基于JSON的Ollama和LangChain agent

到目前为止,我们都可能意识到,通过为LLMs提供额外的工具,我们可以显著增强它们的功能。

例如,即使是ChatGPT在付费版本中也可以直接使用Bing搜索和Python解释器。OpenAI更进一步,为工具使用提供了经过优化的LLM模型,您可以将可用的工具和提示一起传递给API端点。

然后LLM决定是否可以直接提供回答,或者是否应该首先使用任何可用的工具。

请注意,这些工具不仅仅用于获取额外的信息;它们可以是任何东西,甚至可以让LLMs预订晚餐。我之前实施过一个项目,允许LLM通过一组预定义的工具与图数据库进行交互,我称之为语义层。

一个与图数据库交互的代理LLM。图片由作者提供。

本质上,这些工具通过提供动态、实时的信息访问、通过记忆进行个性化以及通过知识图谱对关系进行复杂的理解,来增强像GPT-4这样的LLM。

它们共同使LLM能够提供更准确的推荐,随着时间的推移了解用户的偏好,并获得更广泛的最新信息,从而实现更具互动性和适应性的用户体验。

正如提到的那样,除了在查询时能够检索到额外的信息外,它们还给LLM提供了一种影响他们环境的选择,例如在日历中预订会议。

虽然OpenAI为我们提供了精细调整的模型来进行工具使用,但事实是,大多数其他LLMs在函数调用和工具使用方面都不及OpenAI水平。

我已经尝试了Ollama中大部分可用的模型,大多数都难以始终生成可用于驱动代理的预定义结构化输出。另一方面,有一些模型是针对函数调用进行了优化的。

然而,这些模型采用了一种自定义的提示工程模式来进行函数调用,但这种模式并没有很好地记录,或者它们不能用于除了函数调用之外的任何其他用途。

最终,我决定遵循现有的LangChain实现,使用基于JSON的代理,使用Mixtral 8x7b LLM。我将Mixtral 8x7b用作电影代理,通过语义层与Neo4j进行交互,Neo4j是一种本地图数据库。代码可作为Langchain模板和Jupyter笔记本提供。如果你对工具的实现方式感兴趣,可以查看我之前的博客文章。在这里,我们将讨论如何实现基于JSON的LLM代理。

语义层中的工具

LangChain文档中的示例(JSON代理,HuggingFace示例)使用的是只有一个字符串输入的工具。由于语义层中的工具使用稍微复杂一些的输入,我不得不深入研究一下。这是一个推荐工具的示例输入。

all_genres = ["Action","Adventure","Animation","Children","Comedy","Crime","Documentary","Drama","Fantasy","Film-Noir","Horror","IMAX","Musical","Mystery","Romance","Sci-Fi","Thriller","War","Western",
]class RecommenderInput(BaseModel):movie: Optional[str] = Field(description="movie used for recommendation")genre: Optional[str] = Field(description=("genre used for recommendation. Available options are:" f"{all_genres}"))

推荐工具有两个可选输入:电影和类型。此外,我们使用一个可用值的枚举来表示类型参数。

虽然输入并不是非常复杂,但仍比单个字符串输入更先进,因此实现方式必须稍有不同。

基于JSON的LLM代理的提示

在我的实现中,我从LangChain hub中现有的 hwchase17/react-json 提示中获得了很大的灵感。该提示使用以下系统消息。

Answer the following questions as best you can. You have access to the following tools:{tools}The way you use the tools is by specifying a json blob.
Specifically, 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).The only values that should be in the "action" field are: {tool_names}The $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:```
{{"action": $TOOL_NAME,"action_input": $INPUT
}}
```ALWAYS use the following format:Question: the input question you must answer
Thought: you should always think about what to do
Action:
```
$JSON_BLOB
```
Observation: the result of the action
... (this Thought/Action/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input questionBegin! Reminder to always use the exact characters `Final Answer` when responding.

提示从定义可用工具开始,稍后我们将介绍。提示的最重要部分是指示LLM输出应该是什么样子的。当LLM需要调用一个函数时,应该使用以下JSON结构:

{{"action": $TOOL_NAME,"action_input": $INPUT
}}

这就是为什么它被称为基于JSON的代理:当LLM想要使用任何可用工具时,我们指示它生成一个JSON。然而,这只是输出定义的一部分。完整的输出应该具有以下结构:

Thought: you should always think about what to do
Action:
```
$JSON_BLOB
```
Observation: the result of the action
... (this Thought/Action/Observation can repeat N times)
Final Answer: the final answer to the original input question

LLM应该在输出的思考部分解释它正在做什么。当它想要使用任何可用的工具时,应该将动作输入提供为JSON blob。

观察部分保留给工具输出,当代理决定可以向用户返回答案时,应使用最终答案键。以下是使用此结构的电影代理的示例。

在这个例子中,我们要求代理人推荐一部好的喜剧片。由于代理人可用的工具之一是推荐工具,它决定利用推荐工具,通过提供JSON语法来定义其输入。幸运的是,LangChain具有内置的JSON代理输出解析器,所以我们不必担心实现它。接下来,LLM从工具中获得一个响应,并将其作为提示中的观察。

由于工具提供了所有所需的信息,LLM决定它已经有足够的信息来构建最终答案,并将其返回给用户。

我注意到很难促使工程师Mixtral只在需要使用工具时使用JSON语法。在我的实验中,当它不想使用任何工具时,有时会使用以下JSON动作输入。

{{"action": Null,"action_input": ""
}}

LangChain中的输出解析函数不会忽略空或类似的操作,而是返回一个错误,指出未定义空工具。我试图向工程师提供解决这个问题的提示,但无法以一致的方式做到。

因此,我决定添加一个虚拟的闲聊工具,当用户想要闲聊时,代理可以调用它。

response = ("Create a final answer that says if they ""have any questions about movies or actors"
)class SmalltalkInput(BaseModel):query: Optional[str] = Field(description="user query")class SmalltalkTool(BaseTool):name = "Smalltalk"description = "useful for when user greets you or wants to smalltalk"args_schema: Type[BaseModel] = SmalltalkInputdef _run(self,query: Optional[str] = None,run_manager: Optional[CallbackManagerForToolRun] = None,) -> str:"""Use the tool."""return response

这样,代理可以在用户打招呼时决定使用一个虚拟的Smalltalk工具,我们不再遇到解析空或缺失工具名称的问题。

这个解决方法非常有效,所以我决定保留它。正如提到的,大多数模型没有经过训练来产生行动输入或文本,如果不需要行动,我们必须使用当前可用的内容。

然而,有时候模型在第一次迭代时成功地不调用任何工具,这取决于情况。但是给它一个像smalltalk工具这样的逃逸选项似乎可以防止异常。

在系统提示中定义工具输入

如前所述,我必须弄清楚如何定义稍微复杂的工具输入,以便LLM能够正确解释它们。

有趣的是,在实施自定义函数之后,我发现了一个现有的LangChain函数,它将自定义的Pydantic工具输入定义转换为Mixtral可以识别的JSON对象。

from langchain.tools.render import render_text_description_and_argstools = [RecommenderTool(), InformationTool(), Smalltalk()]tool_input = render_text_description_and_args(tools)
print(tool_input)

生成以下字符串描述:

"Recommender":"useful for when you need to recommend a movie",
"args":{{"movie":{{"title":"Movie","description":"movie used for recommendation","type":"string"}},"genre":{{"title":"Genre","description":"genre used for recommendation. Available options are:['Action', 'Adventure', 'Animation', 'Children', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'IMAX', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western']","type":"string"}}}
},
"Information":"useful for when you need to answer questions about various actors or movies",
"args":{{"entity":{{"title":"Entity","description":"movie or a person mentioned in the question","type":"string"}},"entity_type":{{"title":"Entity Type","description":"type of the entity. Available options are 'movie' or 'person'","type":"string"}}}
},
"Smalltalk":"useful for when user greets you or wants to smalltalk",
"args":{{"query":{{"title":"Query","description":"user query","type":"string"}}}
}

我们可以简单地将这个工具描述复制到系统提示中,Mixtral就能够使用定义好的工具,这非常酷。

 结论

JSON-based agent的大部分工作是由Harrison Chase和LangChain团队完成的,我对此表示感谢。我所要做的就是找到拼图的碎片并将它们组合起来。正如前面提到的,不要期望与GPT-4一样的代理性能水平。然而,我认为像Mixtral这样更强大的OSSLLMs可以作为代理使用(比GPT-4需要更多的异常处理)。

我期待更多的开源LLMs被调整得更好作为代理。

代码可作为Langchain模板和Jupyter笔记本提供。

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

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

相关文章

js方法 提前结束循环

http://t.csdnimg.cn/j0gkOhttp://t.csdnimg.cn/j0gkO 一、各种循环方法如何跳出整个循环? 对于forEach()方法,目前似乎没有比较优雅的跳出整个循环的方法,如果你实在要用forEach()方法并且需要在某种条件下跳出整个循环提高遍历效率&#x…

政安晨:【掌握AI的深度学习工具Keras API】(二)—— 【使用内置的训练循环和评估循环】

渐进式呈现复杂性,是指采用一系列从简单到灵活的工作流程,并逐步提高复杂性。这个原则也适用于模型训练。Keras提供了训练模型的多种工作流程。这些工作流程可以很简单,比如在数据上调用fit(),也可以很高级,比如从头开…

uniapp实战:父子组件传参之子组件数量动态变化

需求说明 现有的设置单元列表,每个带有虚线加号的可以看做是一组设置单元,点击加号可以添加一组设置单元.点击设置单元右上角可以删除对应的设置单元. 实现思路说明 利用数组元素添加或是删除的方式实现页面数量动态变化.由于每个设置单元内容都相同所以单独封装了一个子组件.…

高效备考2025年AMC8数学竞赛:2000-2024年AMC8真题练一练

如何提高小学和初中数学成绩?小学和初中可以参加的数学竞赛有哪些?不妨了解一下AMC8美国数学竞赛,现在许多小学生和初中生都在参加这个比赛。如果孩子有兴趣,有余力的话可以系统研究AMC8的历年真题,即使不参加AMC8竞赛…

YOLOv9大幅度按比例减小模型计算量!加快训练!

一、代码及论文链接: 代码链接:GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information 论文链接:https://github.com/WongKinYiu/yolov9/tree/main 二…

02| JVM堆中垃圾回收的大致过程

如果一直在创建对象,堆中年轻代中Eden区会逐渐放满,如果Eden放满,会触发minor GC回收,创建对象的时GC Roots,如果存在于里面的对象,则被视为非垃圾对象,不会被此次gc回收,就会被移入…

深度学习500问——Chapter02:机器学习基础(1)

文章目录 前言 2.1 基本概念 2.1.1 大话理解机器学习本质 2.1.2 什么是神经网络 2.1.3 各种常见算法图示 2.1.4 计算图的导数计算 2.1.5 理解局部最优与全局最优 2.1.5 大数据与深度学习之间的关系 2.2 机器学习学习方式 2.2.1 监督学习 2.2.2 非监督式学习 2.2.3 …

TVM 和模型优化的概述(1)

文章目录 1. 从 Tensorflow、PyTorch 或 Onnx 等框架导入模型(model)。2.翻译成 Relay3. lower 到 张量表达式。4. 使用 auto-tuning 模块 AutoTVM 或 AutoScheduler 搜索最佳 schedule。5. 选择最佳配置进行模型编译。6. lower 到 TIR。7. 编译成机器码…

波奇学Linux:共享内存

进程通信的前提:不同的进程看到同一份的资源 直接原理:同一块物理内存映射到不同进程的共享区 共享内存拆解: 1.申请内存,通过页表映射到进程地址空间 2.返回首地址,便于进程利用 3.释放共享内存,去关联 4.内存的申请…

flex的5种常见使用

Flex 布局教程:语法篇 文章目录 一.基本概念二 例子 其实我每次记一个样式标签,都是根据英文来记,但是justify-content和align-items确实让我迷惑,这次我打算只记 justify-content属性定义了项目在主轴上的对齐方式,好好总结一下用法~ 一.基本概念 采用 Flex 布局…

SpringBoot 事务失效及其对应解决办法

简介 本文主要讲述Spring事务会去什么情况下失效及其解决办法 Spring 通过AOP 进行事务控制,如果操作数据库报异常,则会进行回滚;如果没有报异常则会提交事务;但是,如果Spring 事务失效,会导致数据缺失/重…

【STM32】STM32学习笔记-独立看门狗和窗口看门狗(47)

00. 目录 文章目录 00. 目录01. WDG概述02. 独立看门狗相关API2.1 IWDG_WriteAccessCmd2.2 IWDG_SetPrescaler2.3 IWDG_SetReload2.4 IWDG_ReloadCounter2.5 IWDG_Enable2.6 IWDG_GetFlagStatus2.7 RCC_GetFlagStatus 03. 独立看门狗接线图04. 独立看门狗程序示例105. 独立看门…

OD(12)之Mermaid思维导图(Mindmap)

OD(12)之Mermaid思维导图(Mindmap)使用详解 Author: Once Day Date: 2024年2月29日 漫漫长路才刚刚开始… 全系列文章可参考专栏: Mermaid使用指南_Once_day的博客-CSDN博客 参考文章: 关于 Mermaid | Mermaid 中文网 (nodejs.cn)Mermaid | Diagramming and charting tool…

postman传参与返回值切换为左右显示的操作

目录 第一步 点击“Settings”,在下拉框选择“Settings” 第二步 在默认打开的General页面,参照下图改动两处 第一步 点击“Settings”,在下拉框选择“Settings” 第二步 在默认打开的General页面,参照下图改动两处 附上修改后…

opencv中的rgb转gray的计算方法

转换原理 在opencv中,可以使用cv2.cvtColor函数将rgb图像转换为gray图像。示例代码如下, import cv2img_path "image.jpg" image cv2.imread(img_path) gray_image cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) mean gray_image.mean() pri…

【AI Agent系列】【MetaGPT多智能体学习】4. 基于MetaGPT的Team组件开发你的第一个智能体团队

本系列文章跟随《MetaGPT多智能体课程》(https://github.com/datawhalechina/hugging-multi-agent),深入理解并实践多智能体系统的开发。 本文为该课程的第四章(多智能体开发)的第二篇笔记。主要是对MetaGPT中Team组件…

Payment Without Change

题目链接&#xff1a;Problem - 1256A - Codeforces 解题思路&#xff1a; 题目的大致意思就是手中的硬币数拿出若干枚正好等于s&#xff0c;分三种情况 .如果n > s && b < s,输出no .如果b > s,输出yes .如果n * (a < (s / n) ? a : (s / n)) b >…

【iOS ARKit】RealityKit 同步机制

协作 Session 可以很方便地实现多用户之间的AR体验实时共享&#xff0c;但开发者需要自行负责并确保AR场景的完整性&#xff0c;自行负责虚拟物体的创建与销毁。为简化同步操作&#xff0c;RealityKit 内建了同步机制&#xff0c;RealityKit 同步机制基于 Multipeer Connectivi…

Python标准库sys常用函数、方法及代码实战解析【第108篇—标准库sys常用函数】

Python标准库sys常用函数、方法及代码实战解析 在Python的标准库中&#xff0c;sys 模块是一个常用而强大的工具&#xff0c;它提供了与Python解释器交互的函数和变量。本文将介绍sys模块的一些常用函数和方法&#xff0c;并通过实际的代码实例来解析它们的用法。 1. sys.argv…

2024.2.19

1.TCP模型 服务器端 #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){perror("socket error"…