LLM Agent 零微调范式:ReAct 与 Self Ask
在之前的章节中,我们分别介绍了思维链(Chain of Thought)的使用、原理及其在小模型上的应用。本章正式进入应用层面,探讨如何将思维链与工具使用结合,构建人工智能代理(AI Agent)。
为什么需要 AI Agent?
AI Agent 可以解决哪些问题?我们可以从两个视角来理解:
- 赋能模型:如果说 LLM 是大脑,那 Agent 提供了手脚和感官。
- 感官:获取真实世界的信息,包括实时信息(如天气、金融市场、交通状况)、私有信息(如用户个人数据)以及多模态信息(如声音和图像)。
- 手脚:获得与真实世界交互的能力,例如运行 Python 脚本、调用搜索引擎、预定机票酒店等。
- 模型赋能我们:Agent 加持的大模型作为更优的数据和任务中介/代理,赋予了我们与任意数据类型交互的能力。大模型正在重构数据和信息的处理方式,从之前的结构化数据为主向更多的非结构化数据转变。
OpenAI 应用研究主管 Lilian Weng 将人工智能代理(AI Agent)分成了以下三个部分:规划模块、工具调用模块和记忆模块。
- 规划:如何对问题进行拆解得到解决路径,即模型推理步骤。
- 工具:支持哪些工具使用,如何进行工具选择,并生成调用工具的请求。
- 记忆:短期记忆包括工具的返回值、已经完成的推理路径;长期记忆包括可访问的外部长期存储,例如知识库。
本文将结合 LangChain 介绍无需微调,使用 few-shot 或 zero-shot prompt 来生成推理和工具调用模板的两个方案:ReAct 和 Self Ask。
Self Ask
Self Ask 提出了一种把问题拆解成子问题的 Prompt 范式。每一步模型都会自我提问是否可以把问题改写/拆解成一个简单的子问题,并进行回答。回答时可以调用搜索工具来获得答案,然后根据工具返回结果,继续进行自我提问,直到获得最终答案。其实自我提问的推理形式并不是核心,核心是引导模型来进行问题拆解,也就是开头提到的规划能力。
原理
论文提出之所以需要把原始的思维链改造成一步步自我提问的形式,是因为发现模型在回答复杂问题的时候,虽然可以正确回答其中的子问题,但是却无法回答由子问题组合起来的复杂问题。作者称之为 Compositionality Gap(组合性差距)。
举个栗子:模型可以正确回答贾斯汀比伯是哪年出生的?以及谁是 94 年大师赛的冠军?但是模型无法回答谁是贾斯汀比伯出生那一年的大师赛的冠军?而通过引入问题拆解的推理方式,可以很好解决这个问题。
应用
我们来看下 LangChain 的 Self Ask 实现。这里我们把中间步骤拆解开,使用了 Google 搜索工具和 GPT3.5。
import os
from langchain.agents.loading import AGENT_TO_CLASS
from langchain.agents.agent import AgentExecutor
from langchain.agents import AgentType, Tool
from langchain import OpenAI, SerpAPIWrapper
# 定义大模型和搜索工具
llm = OpenAI(temperature=0, openai_api_key="你的 Key")
search = SerpAPIWrapper(params={
"engine": "google",
: ,
: ,
}, serpapi_api_key=)
tools = [
Tool(
name=,
func=search.run,
description=
)
]
agent_cls = AGENT_TO_CLASS[AgentType.SELF_ask_with_search]
agent = agent_cls.from_llm_and_tools(llm, tools)
chain = AgentExecutor.from_agent_and_tools(agent, tools, return_intermediate_steps=)


