React Agent 自定义实现

news2024/10/19 22:00:52

目录

背景

langchin 中的 agent

langchin 中 agent 的问题

langchain 的 agent 案例

自定义 React Agent

大模型

工具定义

问题设定

问题改写,挖掘潜在意图

React Prompt

下一步规划

问题总结

代码


背景

之前使用过 langchian 中的 agent 去实现过一些案例,angchian 的 React Agent 是有问题的,且内部代码有点难看懂,所以自己来根据 React 思想,灵活来实现试一下。

可以先看看我自定义实现的逻辑图,后面详细说明:

langchin 中的 agent

langchian 中的几种 agent 怎么用,我都看过了,也整理了一下了,那些能用,那些有问题的可以看注释,代码链接:https://github.com/5zjk5/prompt-engineering

langchin 中 agent 的问题

先来说说我用过的发现的问题,就是它的 React agent 有点问题,只调用一个工具就结束了,详细实验的文章:langchain 的 agent + tool 使用_langchain agent tool-CSDN博客

想去看看代码到底怎么运行的,发现太难看懂了。

后面在我自己实现 React agent 的时候,突然发现,跟 prompt 关系挺大的,langchian 那个 prompt 应该是根据 openai 的去写的,这是我目前想到只能调用一个工具的原因。

langchain 的 agent 案例

GitHub - 5zjk5/prompt-engineering: prompt 工程项目案例

自定义 React Agent

大模型

用的智谱 glm-4-air,如果换了模型,效果还不太稳定,需要调 prompt。

工具定义

定义两个工具,一个是 tavily 的搜索,去官网开通账号就可以获得一个 api,免费调用 1000 次;

一个工具是根据名字查询身高的自定义函数

from tavily import TavilyClient
from llm.llm_api_key import TAVILY_API_KEY
import time


def tavily_search(query):
    try:
        # Step 1. Instantiating your TavilyClient
        tavily_client = TavilyClient(api_key=TAVILY_API_KEY)

        # Step 2. Executing a Q&A search query
        answer = tavily_client.qna_search(query=query)

        # Step 3. That's it! Your question has been answered!
        return answer
    except:
        time.sleep(1)
        # Step 1. Instantiating your TavilyClient
        tavily_client = TavilyClient(api_key=TAVILY_API_KEY)

        # Step 2. Executing a Q&A search query
        answer = tavily_client.qna_search(query=query)

        # Step 3. That's it! Your question has been answered!
        return answer


def height_search(name):
    height_dic = {
        "张三": 180,
        "李四": 175,
        "王五": 170,
        "赵六": 165,
        "钱七": 160,
        "孙八": 175,
        "周九": 170,
        "吴十": 165,
        "郑十一": 180,
        "王十二": 175,
        "李十三": 170,
        "赵十四": 165,
        "钱十五": 180,
        "孙十六": 175,
    }
    return height_dic.get(name)

工具描述,要让大模型理解工具,需要定义描述,这里参考的智谱官方的工具的描述写法:

tavily_search_tool = {
        "type": "function",
        "function": {
            "name": 'tavily_search',
            "description": "根据用户查询,去搜索引擎,返回搜索结果",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "description": "用户搜索内容 query",
                        "type": "string"
                    },
                },
                "required": ["query"]
            }
        }
      }

height_search_tool = {
        "type": "function",
        "function": {
            "name": 'height_search',
            "description": "只要是有姓名,身高关键字,都需要使用此工具根据姓名,查询对应身高,每次只能查询一个人的身高",
            "parameters": {
                "type": "object",
                "properties": {
                    "name": {
                        "description": "指具体的姓名或名字",
                        "type": "string"
                    },
                },
                "required": ["name"]
            }
        }
      }

问题设定

设定一个问题:

这个问题潜在意图是查询钱七,李四身高,并且搜索大模型定义,是想调用身高查询工具 2 次,搜索工具 1 次。

问题改写,挖掘潜在意图

为什么加这一步呢?因为把问题传给大模型后发现一个问题,它可能发现不了潜在意图,例如这里潜在意图要查询身高,问题中没有明显提出,大模型思考结果:

这样的话就只使用搜索工具就结束了,所以加了一步问题改写,去发现潜在意图,是利用大模型能力去做的,用 prompt,改写结果成功识别出潜在意图,并思考出要调用哪个工具:

尽你所能改写以下问题,可以有多个答案,可以参照以下工具进行改写,识别用户潜在意图:
```{tools}```
Question:`{query}`
Answer 按照以下格式,每一点代表一个意图,如果需要用到工具的需要列出工具名字,不需要具体参数:
```
1. 
2. 
...
```

React Prompt

React agent 核心的 prompt 怎么让模型自动规划,先来看 langchain 中的写法:

Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer

Thought: you should always think about what to do

Action: the action to take, should be one of [{tool_names}]

Action Input: the input to the action

Observation: the result of the action

... (this Thought/Action/Action Input/Observation can repeat N times)

Thought: I now know the final answer

Final Answer: the final answer to the original input question

Begin!

Question: {input}

Thought:{agent_scratchpad}

传入变量 tool 为所有工具,tool_names 为所有工具名称列表,input 问题输入,agent_scratchpad 思考要做什么,怎么做。

参照进行改编:

尽你所能回答以下问题。您可以使用以下工具:
```{tools}```

严格使用以下 JSON 格式:
```
{{
    Question: 根据 thought 当前需要回答的问题,此字段必须存在
    Thought: 对于 Question 要做什么,此字段必须存在
    Action: {{'tool': 要采取的动作,应该是[{tool_names}]之一,如果不需要工具可以空着}}
    Action Input: 动作的输入,是一个 JSON 格式,此字段必须存在,如果不需要输入可以空着
    Observation: 行动的结果,此字段必须存在,默认为空
}}
```
(Question/Thought/Action/Action Input/Observation 五个字段必须存在,以上步骤只能重复 1 次)

开始吧!
Question:`{query}`
thought:`{agent_scratchpad}`

根据 agent_scratchpad 每次运行得到 json 的 action,接着提取工具名及参数,去进行工具调用,这里因为是 json,格式控制好了提取就方便了。

使用完工具后,把结果赋值给 Observation。

下一步规划

agent_scratchpad 就是下一步规划的思考,用 prompt 去进行规划,传给已经执行的 action,问题及思考,让自动规划下一步应该做什么:

# 背景
有一个问题 Question,已经有了对这个问题的思考 Thought,已执行的思考 Action,需要根据这些信息去规划出下一步应该做什么。

# 输入
## Question:`{query}`
## Thought:`{thought}`
## Action:`{all_action_res}`

# 思考推理:
- 1、参考 Question 仔细理解 Thought,思考 Action 还有哪些没有行动。
- 2、判断你下一步做什么行动,不能过于发散过多的行动,必须根据步骤 1 的思考。
- 3、确保你的回答在语义上与 Action 中的内容不重复是一个全新的步骤。
- 4、若 Thought 已经全部执行了,直接回答`no`。

# 输出要求(严格按照以下要求输出)
- 回答需要用一句话清晰的总结下一步需要做什么,不需要其他任何信息。
- 如果没有需要做的了,直接输出`no`,不需要其他任何信息,不需要解释任何理由。

这里遇到一个问题,就是可能会一直重复规划,导致死循环,在代码中加了判断,理论上开始重复规划了,说明已经没有可以给出新的规划了,那就结束吧。

问题总结

所有 action 的结果,用了一个列表保存的,最后用大模型自己去总结去回答问题就可以了。

D:\programming\dev_env\anaconda\anaconda3\python.exe "D:\Python_project\NLP\大模型学习\prompt-engineering\自定义 React Agant\run_agent.py" 
D:\programming\dev_env\anaconda\anaconda3\Lib\site-packages\langchain\callbacks\__init__.py:37: LangChainDeprecationWarning: Importing this callback from langchain is deprecated. Importing it from langchain will no longer be supported as of langchain==0.2.0. Please import from langchain-community instead:

`from langchain_community.callbacks import get_openai_callback`.

To install langchain-community run `pip install -U langchain-community`.
  warnings.warn(
输入 token:103/输出 token:268/总共 token:371/
问题改写,识别潜在意图:
1. 识别用户提到的“身高比较高的小伙子”和“长得像钱七”,可能需要查询钱七的身高信息(使用工具:height_search)。
2. 识别用户提到的“还有他跟他身高差不多的兄弟李四”,可能需要查询李四的身高信息(使用工具:height_search)。
3. 用户对“大模型”表示不清楚,需要解释或搜索“大模型”的定义和相关信息(使用工具:tavily_search)。
=====================================
输入 token:53/输出 token:376/总共 token:429/
解决此问题的思考 Thought:
根据用户的问题,我们需要查询钱七和李四的身高信息,并获取关于“大模型”的解释和相关信息。因此,我们需要使用height_search工具来查询身高信息,以及使用tavily_search工具来搜索大模型的相关内容。
=====================================
输入 token:89/输出 token:426/总共 token:515/
{'Action': {'tool': 'height_search'},
 'Action Input': {'name': '钱七'},
 'Observation': 160,
 'Question': '1. 识别用户提到的“身高比较高的小伙子”和“长得像钱七”,可能需要查询钱七的身高信息(使用工具:height_search)。',
 'Thought': '需要使用工具查询钱七的身高信息。'}
=====================================
输入 token:12/输出 token:289/总共 token:301/
下一步需要做什么:
需要使用工具查询李四的身高信息。
=====================================
输入 token:60/输出 token:435/总共 token:495/
{'Action': {'tool': 'height_search'},
 'Action Input': {'name': '李四'},
 'Observation': 175,
 'Question': '查询李四的身高信息。',
 'Thought': '使用height_search工具查询李四的身高。'}
=====================================
输入 token:14/输出 token:301/总共 token:315/
下一步需要做什么:
使用tavily_search工具搜索大模型的相关内容。
=====================================
输入 token:61/输出 token:437/总共 token:498/
{'Action': {'tool': 'tavily_search'},
 'Action Input': {'query': '大模型是什么意思'},
 'Observation': 'Based on the data provided, the term "大模型" (Big Model) refers '
                'to a method or technology used in the fields of machine '
                'learning and artificial intelligence to handle large-scale '
                'data and complex models. These models are typically '
                'constructed using deep neural networks with a large number of '
                'parameters, ranging from billions to even trillions. The '
                'purpose of big models is to improve model expressive power '
                'and predictive performance, enabling them to handle more '
                'complex tasks and datasets effectively. Big models play a '
                'crucial role in addressing challenges posed by increasing '
                'data volumes and model complexities in the field of AI and '
                'machine learning.',
 'Question': '大模型是什么意思?',
 'Thought': '使用搜索引擎查询大模型的相关信息。'}
=====================================
输入 token:10/输出 token:311/总共 token:321/
开始生成重复步骤,或已执行 action 过多,判断结束了!重复步骤:使用搜索引擎查询大模型的相关信息。
下一步需要做什么:
no
=====================================
输入 token:109/输出 token:332/总共 token:441/
最终答案:
根据您的描述,钱七的身高是160厘米,而李四的身高是175厘米。至于您提到的“大模型”,这是一种在机器学习和人工智能领域中使用的方法或技术。大模型通常指的是具有大量参数(从数十亿到数万亿不等)的深度神经网络模型。这些模型的目的是提高表达能力和预测性能,使它们能够更有效地处理大规模数据和复杂任务。

简而言之,大模型是为了应对人工智能和机器学习领域中数据量增加和模型复杂性提升的挑战而发展起来的技术。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Process finished with exit code 0

代码

prompt-engineering/自定义 React Agant at master · 5zjk5/prompt-engineering · GitHub

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

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

相关文章

WordPress监控用户行为回放插件

在数字营销的世界里,了解用户行为是提升用户体验和转化率的关键。nicen-replay 插件,它能够让您轻松回放用户在网站上的每一步操作,从点击到滚动,再到表单填写,每一个细节都清晰可见 nicen-replay,是一款可…

C#从零开始学习(类型和引用)(4)

类型 本章所有的代码都放在 https://github.com/hikinazimi/head-first-Csharp 整型 byte: 0~255sbyte: -128~127short: -32768~32767int: -2147483648~2147483647long: -9223372036854775808~9223372036854775807 以u开头的无符号整数 ushort,uint,ulong 浮点 float: (6~9…

RHCE【远程连接服务器】

目录 一、远程连接服务器简介 二、加密技术简介 SSH工作过程: (1)版本协商阶段 (2)密钥和算法协商阶段 (3)认证阶段 (4)会话请求阶段 (5&#xff0…

KUKA外部自动配置(上)

通过外部PLC对机器人自动运行进程进行控制,其控制原理是:外部PLC通过外部自动运行接口向机器人控制系统发出机器人进程的相关信号(如:运行许可、故障确认、程序启动等),机器人控制系统向外部PLC系统发送有关…

STM32 I2C通信协议详解

文章目录 STM32 I2C通信协议详解一、I2C协议概述二、物理层特性总线结构:引脚定义:电平特性:地址机制: 三、协议层机制起始信号:停止信号:数据有效性:应答信号(ACK)&…

机器学习|Pytorch实现天气预测

机器学习|Pytorch实现天气预测 🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 电脑系统:Windows11 显卡型号:NVIDIA Quadro P620 语言环境:python 3.9.7 编译器&#x…

【Python】selenium遇到“InvalidArgumentException”的解决方法

在使用try……except 的时候捕获到这个错误: InvalidArgumentException: invalid argument (Session info: chrome112.0.5614.0) 这个错误代表的是,当传入的参数不符合期望时,就会抛出这个异常: InvalidArgumentException: invali…

常见TCP/IP协议基础——计算机网络

目录 前言常见协议基础常见协议-基于TCP的应用层协议常见协议-基于UDP的应用层协议常见协议-网络层协议习题自测1.邮件发送协议2.接收邮件协议端口3.建立连接4.层次对应关系5.FTP服务器端口 前言 本笔记为备考软件设计师时的重点知识点笔记,关于常见TCP/IP协议基础…

Java【多线程】wait和notify

目录 wait / notify 由于线程之间是抢占式执⾏的, 因此线程之间执⾏的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执⾏先后顺序. wait / notify 等待/通知 协调线程之间的执行逻辑的顺序的 可以让后执行的逻辑等待先执行的逻辑 虽然无法直接…

缓存框架JetCache源码解析-缓存定时刷新

作为一个缓存框架,JetCache支持多级缓存,也就是本地缓存和远程缓存,但是不管是使用着两者中的哪一个或者两者都进行使用,缓存的实时性一直都是我们需要考虑的问题,通常我们为了尽可能地保证缓存的实时性,都…

word取消自动单词首字母大写

情况说明:在word输入单词后首字母会自动变成大写 (1)点击菜单栏文件 (2)点击“更多”——>“选项” (3)点击“校对”——>“自动更正选项” (4)取消“句首字母大写…

WPF样式详解:行内样式、模板样式和页面样式的全方位分析

Windows Presentation Foundation (WPF) 是微软推出的一种用于构建桌面应用程序的UI框架。WPF 提供了强大的样式和模板机制,允许开发人员以声明的方式定义和复用UI元素的视觉外观。本文将深入探讨WPF的行内样式、模板样式和页面样式,帮助您在实际开发中更…

大数据linux操作系统

第一关:Linux的初体验 答案: cd / ls -a / (里面有空格要注意) 第二关:Linux的常用命令 答案: touch newfile mkdir newdir cp newfile newdir/newfileCpy 第三关:Linux查询命令帮助语句…

我在自动化测试方面犯过的3个大错误

每个人都会犯错误,但不管错误看起来有多糟糕,你都可以恢复过来,更重要的是,从错误中学习。 在软件开发过程的任何领域,从编码到测试,我们都会时不时地犯一些错误。通常,这些错误都很小&#xf…

Linux kernel 堆溢出利用方法

前言 本文还是用一道例题来讲解几种内核堆利用方法,内核堆利用手段比较多,可能会分三期左右写。进行内核堆利用前,可以先了解一下内核堆的基本概念,当然更好去找一些详细的内核堆的基础知识。 概述 Linux kernel 将内存分为 页…

Leetcode 字符串解码

该代码的算法思想可以分为以下几个步骤: 1. 使用栈来处理嵌套结构: 我们需要处理像 k[encoded_string] 这种格式,其中的 encoded_string 可能是嵌套的,即像 3[a2[c]] 这样的输入。因此,我们可以借助 栈(S…

音视频基础知识分享

音视频基础知识分享 RKMedia的各个组件及其交互 首先上图: 考虑到公司业务主要是相机,所以,主要去关注图像数据流,对于音频数据流直接忽略。 图像数据流向: Camera Sensor将光信号转换成电信号(Raw数据&…

【大模型】AI视频课程制作工具开发

1. 需求信息 1.1 需求背景 讲师们在制作视频的过程中,发现录制课程比较麻烦,要保证环境安静,保证录制过程不出错,很容易反复重复录制,为了解决重复录制的工作量,想通过 ai 课程制作工具,来解决…

Rust引用与C++取地址、引用的区别(C++引用、Rust解引用、C++指针)

文章目录 Rust引用与C取地址和引用的比较一、内存安全与管理Rust的内存安全机制C的内存管理 二、引用和取地址Rust的引用C的引用和取地址 三、代码示例比较修改数据的安全性Rust示例C示例 四、结论 Rust引用与C取地址和引用的比较 在程序设计语言的世界里,Rust和C都…

【C++】string类(接口使用详解 下)

我们接着【C】string类(接口使用详解 上)-CSDN博客 继续介绍string的使用。 1.string类对象的修改操作 我们就说一下用的比较多的接口。 1.1 operator 这个接口可以尾插一个字符,或者一个字符串,或者一个对象。 string s1(&qu…