🟡Agent
Agent 是一个基于大语言模型(LLM)的任务执行系统,能够根据用户输入完成推理、工具调用、记忆管理等任务。具备推理、工具调用、记忆、等能力。
既然是基于自然语言分析后进行某些行动(LLM+Action),那必然涉及到提示词和执行机制(Prompt+框架),换句话说,LLM本身是通用模型,但它的行为需要框架约束,才能高效完成特定任务。有些任务需要记忆(对话),有些需要快速推理(零样本),有些需要特定API(函数调用)。Agent 的类型本质上是它的执行框架,
Agent = Prompt+ 执行策略
- Prompt指导 LLM 在框架内如何推理和行动(但是在initialize_agent里被默认写死的)。
- 执行框架决定了 Agent 的能力边界(如是否支持记忆、多轮对话等)。常见框架参数如下:
🟡Agent的策略
在 LangChain 中,Agent 类型本质上是预定义的执行策略,常见类型如下:
类型 | 执行策略 | 适用场景 | 必须参数 |
---|---|---|---|
zero-shot-react-description |
ReAct(推理+行动) | 简单工具调用任务 | llm , tools , prompt (旧方式默认的Prompt不能改,新方式可以显式提供修改) |
conversational-react-description |
带记忆的 ReAct | 多轮对话、智能客服 | llm , tools , prompt , memory (需显式传入) |
openai-functions |
函数调用 | 结构化 API 调用 | llm (需模型本身支持Function Calling), tools (定义为函数格式) 因此对 LLM 型号有要求 |
structured-chat-zero-shot-react |
结构化 ReAct | 稳定的多工具交互 | llm , tools , prompt , memory (结构化对话需上下文) |
plan-and-execute |
先规划再执行 | 复杂任务拆解 | llm , tools , prompt , planner (规划器,可能内置或需额外定义) |
self-ask-with-search |
自问+搜索(RAG) | 知识检索 | llm , tools (含搜索工具,如 WebSearchTool ),prompt |
multi-agent |
多 Agent 协作 | 复杂任务、多角色合作 | llm , tools (含子 Agent),prompt , 可选 memory 或其他协作机制 |
🟡策略是什么?
LangChain 的 Agent 策略本质上是封装好的执行逻辑,为常见任务提供便利,你完全可以手动实现类似功能。
假设任务是让 Agent 计算"2 + 3",我们对比 LangChain 的 create_react_agent
(ReAct 策略)和自己手动构建的策略。
create_react_agent
python
from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain_core.prompts import PromptTemplate
from langchain.tools import Tool
def add_numbers(a, b):
return a + b
tools = [Tool(name="Add", func=add_numbers, description="计算两个数相加,参数:a, b")]
llm = ChatOpenAI(model="gpt-4o")
prompt = PromptTemplate.from_template("""
根据输入推理并调用工具。工具:{tool_names}
输入:{input}
任务:提取两个数字(支持中文或自然语言),调用 Add 工具,格式为 [Add(a, b)]。
""")
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
executor = AgentExecutor(agent=agent, tools=tools)
print(executor.invoke({"input": "二加三等于几"})["output"]) # 输出:5
自己构建
python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o")
def add_numbers(a, b):
return a + b
def my_agent(input_text):
response = llm.invoke(f"""
根据输入提取两个数字(支持中文如"二"或自然语言),返回格式为:a=数字, b=数字
输入:{input_text}
如果无法解析,返回:无法处理
""").content
if "无法处理" in response:
return "无法处理"
try:
a = int(response.split("a=")[1].split(",")[0].strip())
b = int(response.split("b=")[1].strip())
return add_numbers(a, b)
except:
return "无法处理"
print(my_agent("二加三等于几")) # 输出:5
🟡 Agent 新旧方式对比
🔘 旧方式:initialize_agent
- 类型通过显式参数指定(例如
"zero-shot-react-description"
)。 - Prompt 和策略绑定,无法自定义,扩展性差。
python
agent = initialize_agent(tools=tools, llm=llm, agent="zero-shot-react-description")
🔘 新方式:create_xxx_agent
- 类型隐含在构造方法中(例如
create_react_agent
)。 - Prompt 可定制,灵活性更高,能调整语气、逻辑,甚至部分模拟其他策略的功能。
python
prompt = PromptTemplate.from_template("根据输入推理并调用工具。工具:{tool_names} 输入:{input}")
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
🟡 策略的约束
-
能力边界固定:
create_react_agent
:单轮推理 + 工具调用,无记忆支持。create_structured_chat_agent
:多轮对话 + 上下文管理,推理较弱。
-
执行逻辑固定:
- 例如
create_react_agent
的"思考→行动→观察"循环无法通过 Prompt 改为"先记忆再推理"。 - Prompt 只在策略范围内调教 LLM,无法突破框架限制。
- 例如
示例 :在 create_react_agent
中加"记住历史"无效,因无 chat_history
数据支持:
python
prompt = PromptTemplate.from_template("记住历史,回答问题。输入:{input}")
agent = create_react_agent(llm=llm, tools=[])
executor = AgentExecutor(agent=agent, tools=[])
executor.invoke({"input": "我叫张三"}) # 输出:好的,张三
executor.invoke({"input": "我叫啥?"}) # 输出:不知道!
正确实现需用支持记忆的策略:
python
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
prompt = PromptTemplate.from_template("历史:{chat_history} 输入:{input}")
agent = create_structured_chat_agent(llm=llm, tools=[], prompt=prompt)
executor = AgentExecutor(agent=agent, tools=[], memory=memory)
executor.invoke({"input": "我叫张三"}) # 输出:好的,张三
executor.invoke({"input": "我叫啥?"}) # 输出:你叫张三
🟡 新旧方式的变化
- 核心能力未变:旧类型(如 ReAct)在新方式中仍可实现,只是形式从参数改为构造方法。
- 灵活性提升:新方式解耦 Prompt 和策略,可自定义输出格式等:
python
prompt = PromptTemplate.from_template("历史:{chat_history} 输入:{input} 返回JSON")
agent = create_structured_chat_agent(llm=llm, tools=tools, prompt=prompt)
# 输出:{"answer": "你叫张三"}
🟡 框架与工具结合
🔘 工具类型
工具扩展 Agent 能力,LangChain 自带工具包括:
- 记忆 :
ConversationBufferMemory
(全量存储)、ConversationSummaryMemory
(摘要)。 - 检索 :
VectorStoreRetrieverTool
(向量数据库)。 - API :
BingSearchAPIWrapper
(搜索)。 - 代码 :
PythonREPLTool
(执行 Python)。 - 数据库 :
SQLDatabaseToolkit
(SQL 查询)。
也可自定义工具:
python
from langchain.tools import Tool
import requests
def query_osm(query):
url = f"https://nominatim.openstreetmap.org/search?q={query}&format=json"
return requests.get(url).json()
osm_tool = Tool(name="OSM_Search", func=query_osm, description="查询地理信息")
🔘 工具增强策略
例如为 create_react_agent
加"伪记忆":
python
memory_db = {}
def memory_tool(query):
if query.startswith("记住:"): memory_db[query[3:]] = "记住了"
return memory_db.get(query, "不知道")
tool = Tool(name="MemoryTool", func=memory_tool)
agent = create_react_agent(llm=llm, tools=[tool])
executor = AgentExecutor(agent=agent, tools=[tool])
executor.invoke({"input": "记住:我叫张三"}) # 记住了
executor.invoke({"input": "我叫啥?"}) # 你叫张三
🟡 多 Agent 系统
多 Agent 适合复杂任务,通过分工协作提升效率:
- 主 Agent :任务调度(
create_multi_agent
)。 - 子 Agent:记忆(Memory)、检索(RAG)、推理(ReAct)、工具执行(Tool)。
python
multi_agent = create_multi_agent(
llm=llm,
tools=[memory_agent, rag_agent, react_agent], # 子 Agent 作为工具
prompt="根据输入调用合适 Agent"
)
🟡 Prompt 的局限与未来
Prompt 无法改变策略本质,例如在 create_react_agent
中写"你有记忆"无效,因框架无 chat_history
。
- 比喻:策略是引擎(单缸/四缸),Prompt 是油门,踩再狠也改不了引擎。
- 未来:Agent 或能动态切换策略(例如从 ReAct 到对话),无需开发者手动指定。
🟡 总结
- Agent 类型 = 执行策略 + Prompt
- 旧方式(
initialize_agent
):类型固定,Prompt 不可改。 - 新方式(
create_xxx_agent
):策略固定,Prompt 可调。
- 旧方式(
- Prompt 局限:仅在策略范围内有效,无法扩展能力。
- 工具与多 Agent:通过工具和协作突破单一策略限制。
- 选择建议 :
- 简单推理:
create_react_agent
。 - 多轮对话:
create_structured_chat_agent
。 - 高灵活性:函数调用或多 Agent。
- 简单推理: