基于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 question

Begin! 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] = SmalltalkInput

    def _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_args

tools = [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笔记本提供。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

综合练习(二)

目录 列出薪金比 SMITH 或 ALLEN 多的所有员工的编号、姓名、部门名称、领导姓名、部门人数,以及所在部门的平均工资、最高和最低工资 补充 spool Oracle从入门到总裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 列出薪金比 SMITH 或 AL…

我国每年研究生的毕业数量统计分享

本数据集详细记录了自1949年至2021年我国每年研究生的毕业数量(包括硕士和博士学位的毕业生)。在2021年,我国的研究生毕业生人数达到了772,761人,此数字比上一年度增加了44,000人。 统计的数据单位使用的是人数。 数据展示&…

C语言--修饰符(auto、extern、static)与变量(局部变量+全局变量)和函数的关系

其中extern功能和用法上,比较特殊。先了解extern修饰全局变量,我总结为以下几点 为了方便描述,我创建了一个工程,工程包含了两个源文件,main.c和database.c **1):database.c中使用extern时用来…

【压缩技巧】zip压缩包太大怎么变小?

Zip压缩包是压缩文件体积,便于保存的文件格式,但是有些文件实在是太大了,即使是压缩之后,体积仍然很大,那么,zip压缩包太大怎么变小呢?今天分享几种方法。 方法一: 适当减少文件内…

antvX6 - Vue自定义节点,并实现多种画布操作,拖拽、缩放、连线、双击、检索等等

一、 首先 antv x6 分为两个版本 低版本和高版本 我这里是使用的2.0版本 并且搭配了相关插件 例如:画布的图形变换、地图等 个人推荐 2.0版本,高版本配置多,可使用相关插件多,但是文档描述小,仍在更新, 低…

openGauss学习笔记-231 openGauss性能调优-系统调优-资源负载管理-资源负载管理概述

文章目录 openGauss学习笔记-231 openGauss性能调优-系统调优-资源负载管理-资源负载管理概述231.1 功能描述231.2 相关概念**231.2.1 资源管理****231.2.2 控制组****231.2.3 资源池** openGauss学习笔记-231 openGauss性能调优-系统调优-资源负载管理-资源负载管理概述 231.…

java009 - Java调试debugger

1、debugger概述 程序的调试工具,用于查看追踪程序的执行流程,也可以调试程序。 2、debugger调试流程 2.1 如何加断点 2.2 如何运行加了断点的程序 在代码区域右键---->debugger执行 2.3 看哪里 看console窗口 2.4 点哪里 点step into(F7)这个箭…

异常处理(黑马学习笔记)

当前问题 登录功能和登录校验功能我们都实现了,下面我们学习下今天最后一块技术点:异常处理。首先我们先来看一下系统出现异常之后会发生什么现象,再来介绍异常处理的方案。 我们打开浏览器,访问系统中的新增部门操作&#xff0…

potplayer安装

官网 解压运行即可

小(2)型土石坝安全监测设施配置详解

小(2)型土石坝的安全监测是确保大坝稳定、安全运行的重要环节。为此,合理配置安全监测设施显得尤为重要。以下是对小(2)型土石坝安全监测设施配置的详细介绍。 一、渗流量监测 渗流量是反映大坝安全状况的关键指标之一。为准确监测渗流量,我们采用仪器量…

DC28V270V转AC36V115V航空逆变器

在当今的航空航天电源行业中,DC28V270V转AC36V115V航空逆变器发挥着至关重要的作用。作为一种关键的逆变器电源设备,DC28V270V转AC36V115V航空逆变器不仅在航空领域有着广泛的应用,还在许多其他领域发挥着重要作用。 一、DC28V270V转AC36V11…

C语言 常量

常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。 常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。 常量就像是常规的变量,只不过常量的…

【前端素材】推荐优质在线高端蜂蜜商城电商网页Beejar平台模板(附源码)

一、需求分析 1、系统定义 在线高端蜂蜜商城是指一个专门销售高品质、高端蜂蜜产品的电子商务平台。这种商城致力于向消费者提供各种经过精心挑选、具有高营养价值和健康功效的蜂蜜产品。 2、功能需求 在线高端蜂蜜商城是指一个专门销售高品质、高端蜂蜜产品的电子商务平台…

JOSEF约瑟 FHP-33Q/4跳位、合位、电源监视综合控制继电器 凸出式板前接线 0.1-10S

FHP-33系列跳位、合位、电源监视综合控制继电器系列型号:FHP-33A/1跳位、合位、电源监视综合控制继电器;FHP-33A/2跳位、合位、电源监视综合控制继电器;FHP-33A/3跳位、合位、电源监视综合控制继电器;FHP-33A/4跳位、合位、电源监…

数据迁移方法论

文章目录 一. 什么是数据迁移1. 数据迁移与数据整合2. 数据迁移和数据复制3. 数据迁移的主要类型1. Storage migration2. 数据库迁移3. 应用迁移4. 数据中心迁移5. Business process migration(业务流程迁移)6. 云迁移 二. 数据迁移方法1.大爆炸式数据迁…

说一说kong日志级别

Kong官网:The Platform Powering the API World | Kong Inc. Kong Gateway:Kong Gateway | Kong Docs Kong Admin API:Admin API - Kong Gateway - v3.4.x | Kong Docs Kong 企业版社区:API Community for Developers and Industr…

Freesia项目目录结构

目录结构 前端目录: (目录结构来自layui-vue-admin) src文件下 api(前端请求后端服务的路由)assert(一些内置或必要的资源文件)layouts(全局框架样式组件)router&…

OPPO打响AI手机第一枪

明敏 发自 凹非寺 量子位 | 公众号 QbitAI 2024开年,AI趋势依旧高歌猛进。 一边,Sora爆火成为现象级AIGC应用,带动AI再度成为春节后全民热议的第一话题。另一边,手机厂商开始大举All in AI,“放弃传统智能手机”、“…

071:vue+cesium 实现下雨效果

第071个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中实现下雨效果,这里使用着色器来实现实例特效。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共120行)着色代码实现心得:专栏目标示例效果

基于java+springboot动物检疫信息管理系统设计和实现

基于java SSM springboot动物检疫信息管理系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文…