大家都知道AI现在很强大,但其实刚开始没有现在这么智能,刚开始AI其实很多内容都是回答不了的,尤其是一些垂直领域或实时性比较高的问题,比如“今天的天气如何”等,这种需要大模型具备与外界交互的能力,比如获取墨迹天气等等天气平台的实时接口,这个时候OpenAI提出了Function Calling的解决方案,从而让AI大模型拥有了自身能力的外部工具的能力,到现在与Function Calling一样能够让大模型和外部交互的各类Agent是不是随处可见,那什么是Agent?让我们一探究竟!
误区:AI 世界中我们所看到的Agent不是类似之前我们所说的像Nginx之类的代理,这里的Agent不是一种技术,而是一种AI设计模式,在2023年曾经有一条封神的提示词“请一步步思考”,被很多人拿来炫技,这条提示词的专业名词叫“思维链(CoT)”,其实算是Agent的前身。
给大家引入一个知识点:ReAct** = Reason + **Act** (思维链 + 外部工具调用)**
ReAct 思想会让大模型把大问题拆分成小问题,一步步地解决,每一步都会尝试调用外部工具来解决问题,并且还会根据工具的反馈结果,思考工具调用是否出了问题。如果判断出问题了,大模型会尝试重新调用工具。这样经过一系列的工具调用后,最终完成目标。
ReAct简单好理解,一条提示词就可以搞定,让我们开始着手代码环节吧!
要使大模型拥有ReAct 能力,使其变成 Agent,我们需要在向大模型提问时,使用 ReAct Prompt,从而让大模型在思考如何解决提问时,能使用 ReAct 思想。
LangChain 作为目前社区最火的 AI 应用开发脚手架。LangChain 帮大家搭建了一个 prompt 仓库:LangChain Hub。仓库中包含了丰富的 prompt,且具备分类。用户可以非常方便地查找想要的 prompt。
例如:我们在Search中搜索 :react-agent-template
REACT_PROMPT = """
{instructions}
TOOLS:
------
You have access to the following tools:
{tools}
To use a tool, please use the following format:
Thought: Do I need to use a tool? Yes
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Then wait for Human will response to you the result of action by use Observation.
... (this Thought/Action/Action Input/Observation can repeat N times, and once process one action)
When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
Thought: Do I need to use a tool? No
Final Answer: [your response here]
Begin!
New input: {input}
"""
模板会传授大模型按照规定的格式思考和回答问题,这就是在教大模型如何推理和规划,大模型在有了推理和规划能力后就变成了 Agent。
因为 Agent 会将问题拆分成多个子问题,一步一步的进行解决,因此当User提出Question, 大模型从Thought 到 Observation 的过程会执行 N 次,直到大模型认为得到了最终的答案。
ReAct 的执行过程是一个与人类交互的过程。在 Action 和 Action Input 中,大模型会告诉人类需要执行什么工具、以及工具的入参是什么,而具体的工具执行,需要由人类完成。人类完成后,将工具执行结果填入到 Observation,反馈给大模型,直到大模型得到 Final Answer。
langchain-ai/react-agent-template的prompt开头{instructions} 其实是为大模型设置的一个说明书。告诉大模型,使用 {tools} 中定义的工具。因此在 {tools} 里,应该填入工具的描述。
Agent 能否准确地命中工具,很大程度上取决于我们对于工具的描述写得好不好。
# 工具描述
tools = [
{
"name": "get_city_temperature",
"description": "使用该工具可以获取指定城市的气温",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "城市名称",
}
},
"required": ["name"]
},
},
]
# 真正的工具执行函数
def get_city_temperature(name):
if name == "Xi'an":
return "40°c"
elif name == "Chengdu":
return "36°c"
else:
return "未获得该城市的气温"
当User开始提问时,代码需要将 instructions 、tools、tool_names、input 都注入进模板,将模板替换原来的 prompt,发送给大模型。
instructions = "您是一个天气助手,可以回答各城市气候相关的问题"
query = "西安和成都的哪个城市的温度高?"
prompt = REACT_PROMPT.format(instructions=instructions, tools=tools, tool_names="get_city_temperature", input=query)
messages = [{"role": "user", "content": prompt}]
Agent 处理问题会将大问题拆分成一个个的小问题,根据自己的理解选择相应的工具去解决问题。因此作为实际工具调用者的我们,就需要配合大模型完成多轮工具的调用,直到大模型反馈 Final Answer,因此这是一个多轮对话的模式。
while True:
response = send_messages(messages)
response_text = response.choices[0].message.content
print("大模型的回复:")
print(response_text)
final_answer_match = re.search(r'Final Answer:\s*(.*)', response_text)
if final_answer_match:
final_answer = final_answer_match.group(1)
print("最终答案:", final_answer)
break
messages.append(response.choices[0].message)
action_match = re.search(r'Action:\s*(\w+)', response_text)
action_input_match = re.search(r'Action Input:\s*({.*?}|".*?")', response_text, re.DOTALL)
if action_match and action_input_match:
tool_name = action_match.group(1)
params = json.loads(action_input_match.group(1))
if tool_name == "get_city_temperature":
observation = get_city_temperature(params['name'])
print("人为函数的回复:Observation:", observation)
messages.append({"role": "user", "content": f"Observation: {observation}"})
当大模型选择了工具时,会返回 Action 以及 Action Input,当大模型认为得到最终答案时,会返回 Final Answer,返回的示例如下:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。