10.Agent 进阶实践:基于 Planner-Executor-Responder 的多步决策系统实现
这种方式其实有一点不好,就是智能体判断完可能是什么任务后直接就开始执行,得到结果就给了用户,这种方式得到的结果质量可能一般,所以为了提升智能体执行任务返回结果的质量,姚顺雨在2020年提出的了这种AI范式,其核心在于让大语言模型通过“推理-行动-观察”的循环与外部环境交互,以完成复杂任务。咱们需要修改咱们前面写的。
从单步执行到多步决策与状态流转
最近不知道大家有没有关注一些招聘平台的招聘信息,其实看这些平台我相信最多的关键词就Cot、ReAct等,今天咱们主要讲ReAct(Reasoning + Acting),这种范式的提出主要目的是解决纯推理模型易产生“幻觉”和纯行动模型缺乏高层规划的局限性。 这个说法有点抽象,我想换一种说法,这种方式其实是改变智能体的行为方式,咱们前面写到东西其实是一种单步智能体,他的执行过程是这样的:
用户问题 → 选一个工具 → 执行 → 返回结果
这种方式其实有一点不好,就是智能体判断完可能是什么任务后直接就开始执行,得到结果就给了用户,这种方式得到的结果质量可能一般,所以为了提升智能体执行任务返回结果的质量,姚顺雨在2020年提出的了这种AI范式,其核心在于让大语言模型通过“推理-行动-观察”的循环与外部环境交互,以完成复杂任务。可以这样表示:
用户问题 → 思考 → 调工具 → 看结果 → 再思考 → 再决定下一步 → 最终回答
最小循环Agent
今天我们要做的这样一件事,让我们前面写的智能体:
- 先判断用什么工具;
- 调一次工具
- 拿到结果后在做一次总结
- 返回最终答案
也就是实现 状态+节点+流转:
Question → Tool Choice → Tool Output → Final Answer
代码实现
咱们需要修改咱们前面写的agent.py文件。
工具选择planner
首先对咱们的的工具选择进行一定的改造,前面咱们的工具选择是从已定义的工具中选择合适的工具回答问题,这次咱们再补充一点,如果没有合适的工具那么使用大语言模型回答问题:
def choose_tool(query, tools):
tool_desc = "\n".join([
f"{t['name']}: {t['description']}" for t in tools
])
prompt = f"""
You are an AI agent.
Available tools:
{tool_desc}
User question:
{query}
Return JSON:
{{"tool": "...", "input": "..."}}
"""
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}]
)
content = response.choices[0].message.content
try:
return json.loads(content)
except:
return {"tool": "llm", "input": query}
执行工具executor
定义执行工具函数,该函数将会上一步选择工具执行,同时返回响应的中间执行结果:
def execute_tool(decision, tools, rag=None):
tool_name = decision["tool"]
tool_input = decision["input"]
for t in tools:
if t["name"] == tool_name:
if tool_name == "rag":
result = t["func"](tool_input, rag)
else:
result = t["func"](tool_input)
return {
"tool_name": tool_name,
"tool_input": tool_input,
"tool_output": result
}
return {
"tool_name": "none",
"tool_input": tool_input,
"tool_output": "No valid tool found."
}
执行输出responder
咱们前面已经选择的工具,并且得到了中间的执行结果,随后智能体将会观察执行结果,在执行结果的基础上再进行一步思考得出最终执行结果:
def generate_final_answer(query, tool_result):
prompt = f"""
You are an AI assistant
The user asked:
{query}
A tool was used:
Tool name: {tool_result['tool_name']}
Tool input: {tool_result['tool_input']}
Tool output: {tool_result['tool_output']}
Now provide a final helpful answer to the user.
"""
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
最后就是将整个流程穿起来,咱们就得到一个多步决策智能体了:
def run_agent(query, tools, rag=None):
print("=== Agent Start ===")
print("User query:", query)
decision = choose_tool(query, tools)
print("Decision:", decision)
tool_result = execute_tool(decision, tools, rag)
print("Tool result:", tool_result)
final_answer = generate_final_answer(query, tool_result)
print("=== Agent End ===")
return final_answer
这里有个小坑,咱们在选择工具的时候有写这样一段:
try:
return json.loads(content)
except:
return {"tool": "llm", "input": query}
所以咱们还需要再tool.py文件中补一个工具llm_tool:
from datetime import datetime
from llm_utils import client
def rag_tool(query, rag):
return rag.ask(query)
def calculator_tool(expression):
try:
return str(eval(expression))
except:
return "Invalid expression"
def time_tool(_):
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
def llm_tool(query):
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": query}
]
)
return response.choices[0].message.content
TOOLS = [
{
"name": "rag",
"description": "Use for paper/document questions",
"func": rag_tool
},
{
"name": "calculator",
"description": "Use for math calculations",
"func": calculator_tool
},
{
"name": "time",
"description": "Use to get current time",
"func": time_tool
},
{
"name": "llm",
"description": "Use for general questions",
"func": llm_tool
}
]
至此,咱们的代码升级完成,前面的咱们的代码是:
选工具 → 直接返回工具结果
到今天,咱们的代码实现了:
选工具 → 执行工具 → 工具结果作为 observation → LLM 再组织最终答案
如果这篇文章对你有帮助,可以点个赞~
完整代码地址:https://github.com/1186141415/A-Paper-Rag-Agent
更多推荐
所有评论(0)