要想用好 LLM 这两个工具必须节制,一个是 prompt(提示词),一个是 AI agent,而且 prompt 是根本,是能否让AI agent精确分解繁芜任务的关键,prompt 起到 AI agent 和 LLM 对话的翻译器。

AI agent 便是从一个任务出发,通过和 LLM 的多次交互,把这个任务逐步分解为多个子任务,再把这些子任务交付给不同的模块完成,有的模块是已经有第三方供应的能力,有些就须要开拓者自行完成,这就给运用开拓供应了很多便利的条件。
AI agent 就类似一个指挥调度中央,借助于 LLM 这个 AI 来进行赞助决策。

多任务协同提及来大略,但是让人直不雅观理解还是要费些斟酌的,我从事多年微做事架构的开拓,以是我认为 AI agent 的架构类似于微做事架构,都是将繁芜任务拆解为多个可以协同的大略任务来综合完成,我最喜好用的例子便是打算一个四则运算的繁芜表达式,下面就用这个例子详细先容 AIagent 的架构思想和如何利用promptulate 及百度新发布的 V4 LLM 来实现。

问题:利用 LLM 打算类似 a0+a1a2-a3+a4/a5的四则运算结果

运用promptulate框架u0026百度大年夜模型 V4商量AI agent模式

思考:

规则描述,遵照基本的四则运算规则,即先乘除,后加减,相同优先级时从左到右任务分解,按照规则将表达式拆解为多少个独立的+,-,,/运算,分别定义加法、减法、乘法、除法运算,再按照打算的优先顺序多次利用这些独立的算法,知道完成所有打算为什么要自行开拓打算模块,LLM 严格说是措辞概率模型,本身不具备打算能力,以是涉及的打算和逻辑最好利用现有的技能成果或者自行开拓,下面便是一个大略的示例:同样的四则运算技能问题,文心一言给出的答案并禁绝确!

第一步的乘法就错了

精确的答案

支持系统选型:

LLM 选择百度大模型ErnieBot-V4AI agent 框架选择 promptulate

前期准备:

在百度智能云开通千帆大模型的开拓者账号,申请文心大模型4.0的邀测权限,如果没有也可以开通 3.5 版本的权限,利用方法同等安装 promptulate

pip install promptulate

完全代码:

# 利用promptulate框架开拓LLM agent

from promptulate.llms import ErnieBot

import os

from promptulate.agents import ToolAgent

from promptulate.tools import define_tool

from promptulate.utils.logger import enable_log

from promptulate.hook import Hook

import time

os.environ["ERNIE_API_KEY"] = "zQ3fMzn?????H7QeclgDQm"

os.environ["ERNIE_API_SECRET"] = "MDW1?????GEKESRA8qTpxwfs"

@Hook.on_tool_create(hook_type="instance")

def handle_tool_create(args, kwargs):

print("math tool component create")

@Hook.on_tool_start(hook_type="instance")

def handle_tool_start(args, kwargs):

prompt = args[0]

print(f"math tool instance hook start, user prompt: {prompt}")

@Hook.on_tool_result(hook_type="instance")

def handle_tool_result(kwargs):

result = kwargs["result"]

print(f"math tool component result: {result}")

# 识别字符串中的分隔符,然后再按照分隔符隔离数据

def split_str(query: str):

# 判断 query 中是否包含+,-,,/字符,如果包含,则判断包含那个

if '+' in query:

datas=query.split('+')

elif '-' in query:

datas=query.split('-')

elif '' in query:

datas=query.split('')

elif '/' in query:

datas=query.split('/')

elif ',' in query:

datas=query.split(',')

# 去掉datas中每个数据的前后'号和空格

datas=[d.strip().strip("\'") for d in datas]

# 把 datas 里边的字符串转化为 float

datas=[float(d) for d in datas]

return datas

# 自定义加法工具

def addition(query:str):

if not query:

return -1

if query.startswith('[') and query.endswith(']'):

# 去掉query的第1个字符和末了一个字符

query = query[1:-1]

datas=split_str(query)

if len(datas) < 2:

return -1

return datas[0]+datas[1]

# 自定义减法工具

def subtraction(query:str):

if not query:

return -1

datas=split_str(query)

if len(datas) < 2:

return -1

return datas[0]-datas[1]

# 自定义除法工具

def division(query:str):

if not query:

return -1

datas=split_str(query)

if len(datas) < 2:

return -1

return datas[0]/datas[1]

# 自定义乘法工具

def multiplication(query:str):

if not query:

return -1

datas=split_str(query)

if len(datas) < 2:

return -1

return datas[0]datas[1]

# 以韶光戳命名保存文件

def save_file(query:str):

if not query:

return -1

# 文件名称为当前韶光戳,扩展名为txt

fileName='./data/'+str(int(time.time()))+'.txt'

# 将query保存到文件中

with open(fileName, 'w') as f:

f.write(query)

return fileName

def main3():

# 定义利用那个LLM

llm = ErnieBot(model="ernie-bot-4")

# 定义外挂的工具集

tools = [

define_tool(name="addition", description="2个数的和或者字符串中涌现符号+", callback=addition),

define_tool(name="subtraction", description="2个数的差或者字符串中涌现符号-", callback=subtraction),

define_tool(name="multiplication", description="2个数的积或者字符串中涌现符号", callback=multiplication),

define_tool(name="division", description="2个数的商或者字符串中涌现符号/", callback=division),

define_tool(name="save_file", description="保存文件", callback=save_file),

]

# 定义hook集

hooks = [handle_tool_create, handle_tool_start, handle_tool_result]

# 定义agent

agent=ToolAgent(tools=tools,llm=llm,hooks=hooks)

# 利用agent实行繁芜任务

result=agent.run("打算23+8712-878+123121-1233/234+123,将终极结果保持到文件中。
")

print(result)

if __name__ == "__main__":

enable_log()

main3()

备注:

由于百度文心一言大模型 4.0 还在测试阶段,以是还没有集成到 promptulate 框架里边,如果想利用就直接修正 promptulate 框架的 config.py 里边的配置,将百度api 的 URL 改成V4 版本的即可,如下所示:

self.ernie_bot_url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro"

prompt 的关键性对照:

这段代码编写完成后,运行的效果并不理想,LLM 对任务的理解非常不准,就开始疑惑给 AI agent 支配任务的时候描述的不是很准确,导致了任务拆解不合理,就多次对这部分的提示词进行了必要的优化,末了创造好的提示词,效果就很好,下面给出示例。

result=agent.run("按照四则运算的规则,先打算乘除,再进行加减,打算23+8712-878+123121-1233/234+123,将终极结果保持到文件中。
")

也便是要明确见告 AI 的思考规则,这里就提醒利用 AI agent 框架的时候也是要关注提示词的。

运行结果(可能每次的过程不完备相同):

Answer the following questions as best you can.

You have access to the following tools:

addition: 2个数的和或者字符串中涌现符号+

subtraction: 2个数的差或者字符串中涌现符号-

multiplication: 2个数的积或者字符串中涌现符号

division: 2个数的商或者字符串中涌现符号/

save_file: 保存文件

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, must be one of [addition, subtraction, multiplication, division, save_file]

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: 按照四则运算的规则,先打算乘除,再进行加减,打算878+123121-1233/234+123,将终极结果保持到文件中。

Thought:

根据四则运算的规则,须要先打算乘法和除法,然后再进行加法和减法。
因此,我们须要先打算123乘以121和1233除以234,然后将结果与其他数相加或相减,末了将结果保存到文件中。

Action: multiplication

Action Input: 123, 121

Observation: 14883.0

Thought: 接下来须要打算1233除以234。

Action: division

Action Input: 1233, 234

Observation: 5.269230769230769

Thought: 现在我们已经得到了乘法和除法的结果,可以进行加法和减法运算。

Action: addition

Action Input: 878, 14883.0

Observation: 15761.0

Thought: 接下来须要减去1233除以234的结果。

Action: subtraction

Action Input: 15761.0, 5.269230769230769

Observation: 15755.73076923077

Thought: 末了加上123。

Action: addition

Action Input: 15755.73076923077, 123

Observation: 15878.73076923077

Thought: 终极结果为15878.73076923077,须要将结果保存到文件中。

Action: save_file

Action Input: "result.txt", "15878.73076923077"

Observation: ./data/1697782411.txt

Thought: 终极结果已经保存到文件中,任务完成。

Observation: None

Thought: I now know the final answer

Final Answer: None

[DEBUG] 2023-10-20 14:13:35 [pne hook] hooks <('Agent', 'on_agent_result')> mounted_obj <ToolAgent> call hook: <[BaseHookSchema(hook_name='on_agent_result', callback=<function StdOutHook.handle_agent_result at 0x7f9c19f02280>, component_type='Agent')]>

[Agent Result] None

Agent End.

None