Langchain-Chatchat项目:3-Langchain计算器工具Agent思路和实现
本文主要讨论Langchain-Chatchat项目中自定义Agent问答的思路和实现。以"计算器工具"为例,简单理解就是通过LLM识别应该使用的工具类型,然后交给相应的工具(也是LLM模型)来解决问题。一个LLM模型可以充当不同的角色,要把结构化的Prompt模板写好,充分利用LLM的Zero/One/Few-Shot能力。
一.自定义Agent问答
1.1+1等于多少
在线模型使用百度qianfan-api的ernie-bot-turbo,问了一个简单的问题"1+1等于多少",自定义Agent问答的思考过程为:Action: 计算器工具;Action Input: 1+1;Observation: 输出结果为2;Thought: 好的,我回答完毕;Final Answer: 1+1等于2。如下所示:

{'history': [],
'model_name': 'qianfan-api',
'query': '1+1等于多少',
'stream': True,
'temperature': 0.7}
INFO: 127.0.0.1:34592 - "POST /chat/agent_chat HTTP/1.1" 200 OK
> Entering new AgentExecutor chain...
2023-10-07 13:30:04 | INFO | httpx | HTTP Request: POST http://127.0.0.1:7861/chat/agent_chat "HTTP/1.1 200 OK"
count token
{'model': 'qianfan-api', 'prompt': '\n### user: \n Answer the following questions as best you can. You have access to the following tools:\n\n 计算器工具: 进行简单的数学运算\n翻译工具: 翻译各种语言\n天气查询工具: 查询天气\nshell工具: 使用命令行工具输出\n谷歌搜索工具: 使用谷歌搜索\n Use the following format:\n\n Question: the input question you must answer\n Thought: you should always think about what to do\n Action: the action to take, should be one of [计算器工具, 翻译工具, 天气查询工具, shell工具, 谷歌搜索工具]\n Action Input: the input to the action\n Observation: the result of the action\n ... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\n Thought: I now know the final answer\n Final Answer: the final answer to the original input question\n\n Begin!\n\n history:\n \n\n Question: 1+1等于多少\n Thought: \n\n### assistant:'}
2023-10-07 13:30:05 | INFO | httpx | HTTP Request: POST http://127.0.0.1:21004/worker_generate_stream "HTTP/1.1 200 OK"
2023-10-07 13:30:05 | INFO | httpx | HTTP Request: POST https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant?access_token=24.14e5edb75568d4c8dc95c09ea50b5db7.2592000.1699248307.282335-39125244 "HTTP/1.1 200 OK"
{"answer": "这个问题很简单,答案是一"}{"answer": "。"}{"answer": "\n\n"}这个问题很简单,答案是一。
Action: 计算器工具
Action Input: 1+1
Observation: 输出结果为2
Thought: 好的,我回答完毕。
Final Answer: 1+1等于2
> Finished chain.

2.函数调用过程
当dialogue_mode为"自定义Agent问答"时,调用api.agent_chat(prompt, history=history, model=llm_model, temperature=temperature)方法,如下所示:

根据agent_chat(self, query: str, history: List[Dict] = [], stream: bool = True, model: str = LLM_MODEL, temperature: float = TEMPERATURE, no_remote_api: bool = None)中是否为"远程api"走不同的分支。因为本文为有远程api,所有走的response = self.post("/chat/agent_chat", json=data, stream=True)这个方法,如下所示:

然后执行app.post("/chat/agent_chat", tags=["Chat"], summary="与agent对话")(agent_chat),如下所示:

最后执行async def agent_chat()中的async def agent_chat_iterator()方法,如下所示:

拿到model、prompt_template、output_parser后,使用得到链llm_chain = LLMChain(llm=model, prompt=prompt_template),使用llm_chain、output_parser和tool_names得到单个action agent,如下所示:
agent = LLMSingleActionAgent( # 得到agent
llm_chain=llm_chain, # 得到链
output_parser=output_parser, # 得到解析器
stop=["Observation:", "Observation:\n", "<|im_end|>"], # Qwen模型中使用这个
# stop=["Observation:", "Observation:\n"], # 其他模型,注意模板
allowed_tools=tool_names, # 允许的工具
)
把history转换成agent的memory,然后通过agent、tools和memory得到agent_executor,如下所示:
agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, # 得到agent_executor
tools=tools, # 得到工具
verbose=True, # 是否显示日志
memory=memory, # 得到memory
)
二.math agent实现原理
1.Math Prompt模板
觉得实现原理主要是利用了LLM的few-shot的能力,主要是把结构化的Prompt模板写好。如下所示:
_PROMPT_TEMPLATE = """将数学问题翻译成可以使用Python的numexpr库执行的表达式。使用运行此代码的输出来回答问题。
问题: ${{包含数学问题的问题。}}
``text
${{解决问题的单行数学表达式}}
``
...numexpr.evaluate(query)...
``output
${{运行代码的输出}}
``
答案: ${{答案}}
这是两个例子:
问题: 37593 * 67是多少?
``text
37593 * 67
``
...numexpr.evaluate("37593 * 67")...
``output
2518731
答案: 2518731
问题: 37593的五次方根是多少?
``text
37593**(1/5)
``
...numexpr.evaluate("37593**(1/5)")...
``output
8.222831614237718
答案: 8.222831614237718
问题: 2的平方是多少?
``text
2 ** 2
``
...numexpr.evaluate("2 ** 2")...
``output
4
答案: 4
现在,这是我的问题:
问题: {question}
"""
2.LLMMathChain具体使用
主要是根据LLM Model和Prompt模板得到一个LLMMathChain,本质还是LLMMathChain根据Prompt模板执行Python代码进行数学计算,如下所示:
PROMPT = PromptTemplate( # 模板
input_variables=["question"], # 输入变量
template=_PROMPT_TEMPLATE, # 模板
)
def calculate(query: str): # 计算
model = get_ChatOpenAI( # 获取ChatOpenAI
streaming=False, # 是否流式
model_name=LLM_MODEL, # 模型名称
temperature=TEMPERATURE, # 温度
)
llm_math = LLMMathChain.from_llm(model, verbose=True, prompt=PROMPT) # 从llm创建LLMMathChain
ans = llm_math.run(query) # 运行
return ans # 返回答案
觉得一个落地的AI Agent产品,主要是要有一个给力的LLM来做任务的分解,通过不同工具来解决任务,并且可以利用外部的存储能力,最终有一个LLM来合并生成的方案。以一个软件开发小组为例,组长主要是根据需求拆分任务,分配给前端、后端、数据库和测试等,然后负责生成环境的工程师统一合并代码。看似简单的例子,其实里面涉及的情况可能会非常的复杂,比如组长还可以充当不同的角色,相同的角色有弱有强,强的可以接续拆分任务给弱的角色,可以审查代码等。本质上还是一个复杂逻辑推理路径的问题,可以借鉴思维链、思维树、思维图、累积推理等思想。
参考文献:
[1]https://github.com/ai408/Langchain-Chatchat/blob/master/server/agent/math.py
Langchain-Chatchat项目:3-Langchain计算器工具Agent思路和实现的更多相关文章
- Atitit.项目修改补丁打包工具 使用说明
Atitit.项目修改补丁打包工具 使用说明 1.1. 打包工具已经在群里面.打包工具.bat1 1.2. 使用方法:放在项目主目录下,执行即可1 1.3. 打包工具的原理以及要打包的项目列表1 1. ...
- iOS开发小技巧--微博项目中的键盘工具条
微博项目中的键盘工具条 项目中的键盘工具条不能使用inputAccessoryView,因为inputAccessoryView不能实现键盘隐藏的时候,工具条还显示在眼前,如图: 所以,果断决定将工具 ...
- LoadRunner项目结合抓包工具
LoadRunner项目结合抓包工具 常见的抓包工具包括: 1. Http协议 报文分为"请求","应答"两大类. 请求: 方法-URL-协议/版本 ...
- Atitit 项目培训与学校的一些思路总结
Atitit 项目培训与学校的一些思路总结 1.1. Overview implet review OIR学习大法1 1.2. "录取流程,对报名者唯一的要求是学习该项目所必须的先修知识和 ...
- Qt新建项目No valid kits found解决思路
Qt新建项目No valid kits found解决思路 第一次用Qt Creator创建Project时,进入Kit Selection窗口后,会提示No Valid kits found. Pl ...
- 【转】Java 项目UML反向工程转化工具
原文链接:http://www.cnblogs.com/bakari/p/3561207.html 今天在看一个模拟器的源码,一个包里有多个类,一个类里又有多个属性和方法,如果按顺序看下来,不仅不能对 ...
- Java 项目UML反向工程转化工具
今天在看一个模拟器的源码,一个包里有多个类,一个类里又有多个属性和方法,如果按顺序看下来,不仅不能对整个模拟器的框架形成一个大致的认识,而且只会越看越混乱,所以,想到有没有什么工具可以将这些个类以及它 ...
- web项目中日志管理工具的使用
在web项目中,很多时候会用到日志管理工具,常见的日志管理用具有:JDK logging(配置文件:logging.properties) 和log4j(配置文件:log4j.properties) ...
- Maven的安装配置及初次创建项目与java单元测试工具JUnit
Maven 安装 1.把maven安装包解压到某个位置 2.配置M2_HOME环境变量指向这个位置 3.在path环境变量中添加;%M2_HOME%\bin 配置镜像 国内的阿里云镜 ...
- Hyperledger项目中使用的工具
Hyperledger作为一个众多IT厂商参与的项目,全球化的开源社区,其项目的组织形式.流程.工具,都值得借鉴.好工匠离不开好工具,我注意到Hyperledger项目中使用了大量的好工具,包括项目管 ...
随机推荐
- JS逆向实战24—— 补环境过某房地产瑞数4.0
前言 瑞数就不过多介绍了,算是国内 2 线产品中的天花板了.4 代其实难度不高,但要弄出来 确实挺费时间和耐心的.今天就简单来讲讲如何用补环境轻松的过瑞数. 本文首发链接为: https://mp.w ...
- PKCS#11:密码设备与应用程序的密码学接口
密码学在信息安全中扮演着至关重要的角色.为了保护敏感信息.数字身份和网络通信的安全性,密码设备(如硬件安全模块HSM)与应用程序之间的安全通信和互操作性变得至关重要.PKCS#11(Public-Ke ...
- SSH 免秘钥登录
yum -y install expect ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa for i in 192.168.1.11 1 ...
- YbtOJ 做题记录-总集版
感觉每章都开一篇博客过于占据版面 (以及写不动题了想摸一会鱼 于是就有了您现在看到的这篇博客. upd:不知道啥时候咕了.懒得补,那就继续咕着吧(bushi 基础算法 第1章 递推算法 第2章 贪心算 ...
- Python 日期和时间处理教程:datetime 模块的使用
Python 中的日期不是独立的数据类型,但我们可以导入一个名为 datetime 的模块来使用日期作为日期对象. 示例:导入 datetime 模块并显示当前日期: import datetime ...
- 整理unity资料
https://www.cnblogs.com/fly-100/p/3910515.html 协同的概念介绍
- jap复制一条数据插入数据库,报:identifier of an instance of com.kxkd.shop.entity.goods.GoodsSpu was alt
因为修改了jpa实体id 可以先使用springframework的BeanUtils复制一个相同的对象 BeanUtils.copyProperties(source, target); //复制属 ...
- Vite 5.0有哪些新变化?
Rollup 4 Vite 现在使用 Rollup 4,它也带来了一些重大的变化,特别是: 导入断言(assertions 属性)已被重命名为导入属性(attributes 属性). 不再支持 Aco ...
- numpy数组基础
目录 创建数组 多维数组切片 数组属性 使用数组 数组特殊运算符 索引进阶 花式索引 创建数组 在numpy中,创建数组有很多种方法,例如如下的例子: import numpy as np sws_1 ...
- C#简化工作之实现网页爬虫获取数据
公众号「DotNet学习交流」,分享学习DotNet的点滴. 1.需求 想要获取网站上所有的气象信息,网站如下所示: 目前总共有67页,随便点开一个如下所示: 需要获取所有天气数据,如果靠一个个点开再 ...