LangChain 系列教程(六):Agent
介绍
Chain就像一个预先设定好步骤的“流水线”,严格按照我们的指令执行任务。无论是SequentialChain还是RouterChain,它们的路径都是在代码中定义好的。
而Agent可以在面对未知问题时,自己决定需要哪些工具、自己规划步骤、并最终完成任务。
Agent的核心思想是:利用一个语言模型(LLM)作为“大脑”,来决定应该执行哪一系列的动作(Actions)才能完成用户的指令。它不再遵循固定的代码路径,而是进入一个动态的循环,直到任务完成为止。这个循环的每一步都是由AI大脑自主决定的。这个过程我们通常称之为 ReAct 框架,即 Reasoning (推理) + Action (行动)。
Agent 的工作模式
Agent 的工作模式可以分解为一个不断重复的循环,直到找到最终答案:
思考 (Thought):Agent 的“大脑”(LLM)首先分析用户的总目标和当前情况,然后进行推理。“我需要回答‘日本天皇现在几岁?’这个问题。首先,我需要知道他的生日是哪天。我应该用搜索工具来查找这个信息。”
行动 (Action):根据思考结果,大脑决定具体调用哪个工具 (Tool),以及给这个工具什么指令。例如:Action: search(query="日本天皇生日")
观察 (Observation):执行行动后,Agent 会从工具那里得到一个结果(观察)。例如:Observation: "德仁天皇出生于1960年2月23日。"
再次思考 (Thought):Agent 将新的观察结果作为下一步的思考依据。“好的,我已经知道生日了。现在我需要知道今天的日期,然后计算年龄。我可以用计算器工具来完成这个数学运算。”
这个 思考 -> 行动 -> 观察 的循环会一直持续下去,直到大脑认为它已经获得了足够的信息来回答用户的原始问题为止。
Agent 的核心组件
要构建一个 Agent,你需要准备三个关键部分:
大脑 (Agent): 这是控制决策的核心逻辑。它通常是一个特殊的、经过优化的提示词(Prompt),能够引导 LLM 进行“思考->行动->观察”的推理。LangChain 提供了多种预设的 Agent 类型(如 zero-shot-react-description)。
工具 (Tools): 这是 Agent 可以使用的“手和脚”。每个工具都是一个函数,可以执行特定的任务,例如:
谷歌/DuckDuckGo 搜索
计算器
数据库查询
调用某个 API
甚至调用另一个 Chain
关键在于:每个工具都必须有一个清晰的名称和描述,这样“大脑”才能理解每个工具的用途,并在需要时做出正确的选择。
执行器 (AgentExecutor): 这是驱动 Agent 运行的“身体”或“引擎”。它负责执行整个 ReAct 循环:调用 Agent 大脑获得决策、调用相应的工具、将工具返回的结果再传回给大脑,周而复始,直到任务完成。
代码
初始化 LLM 和 Tools
Python import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain.agents import Tool from langchain.chains import LLMMathChain from langchain_community.tools import DuckDuckGoSearchRun
# 加载环境变量 load_dotenv()
# 初始化 LLM (大脑) llm = ChatOpenAI(temperature=0, model="gpt-4o")
# 初始化工具 (手和脚)
# 工具1:搜索 # DuckDuckGoSearchRun 是一个封装好的工具,可以直接使用 search = DuckDuckGoSearchRun() search_tool = Tool( name="Search", func=search.run, description="一个搜索引擎。当你需要回答关于时事、事实或你不知道的信息时,应该使用它。输入应该是具体的问题或搜索词。" )
# 工具2:计算器 # LLMMathChain 可以让 LLM 来执行数学运算 llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=False) calculator_tool = Tool( name="Calculator", func=llm_math_chain.run, description="一个计算器。当你需要进行数学计算或回答关于数学的问题时使用。输入应该是一个完整的数学表达式。" )
# 将所有工具放入一个列表中 tools = [search_tool, calculator_tool]
print("LLM 和工具准备完毕!") print(f"共配置了 {len(tools)} 个工具。") |
创建 Agent 和执行器 (AgentExecutor)
Python from langchain.agents import create_react_agent, AgentExecutor from langchain import hub
# 1. 从 LangChain Hub 中拉取预设的 ReAct 提示词模板 # 这是构建 Agent 的标准做法,确保了提示词的质量和兼容性 prompt = hub.pull("hwchase17/react")
# 2. 创建 Agent (大脑的逻辑) # 这个函数将 LLM、工具列表和提示词组合在一起,创建出 Agent 的核心逻辑 agent = create_react_agent(llm, tools, prompt)
# 3. 创建 Agent 执行器 (驱动循环的身体) # - agent: 上一步创建的 Agent 逻辑 # - tools: Agent 可以使用的工具列表 # - verbose=True: 这是最重要的参数!它会打印出 Agent 的完整思考过程,便于我们观察和理解 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
print("Agent 和执行器创建成功!") |
运行 Agent
Python # 提出一个需要结合搜索和计算才能回答的问题 # 为了让结果稳定,我们明确指定今天的日期 input_question = "日本天皇现在几岁?请将今天的日期按照2025年6月10日计算。"
# 使用 .invoke() 方法运行 AgentExecutor result = agent_executor.invoke({"input": input_question})
print("\n\n----------- 最终答案 -----------") print(result["output"]) |
结果
Python LLM 和工具准备完毕! 共配置了 2 个工具。 /opt/anaconda3/envs/langchain-mcp/lib/python3.11/site-packages/langsmith/client.py:272: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API warnings.warn( Agent 和执行器创建成功!
> Entering new AgentExecutor chain... 要计算日本天皇的年龄,我们需要知道他的出生日期以及计算的日期。日本现任天皇是德仁天皇,他出生于1960年2月23日。我们需要计算从1960年2月23日到2025年6月10日的年龄。
Action: Calculator Action Input: 2025 - 1960Answer: 65我们已经计算出从1960年到2025年间的年份差为65年。接下来,我们需要考虑具体的月份和日期,以确定德仁天皇在2025年6月10日的确切年龄。
德仁天皇出生于1960年2月23日,因此在2025年2月23日他将满65岁。从2月23日到6月10日,他已经过了65岁生日。
Final Answer: 到2025年6月10日,日本天皇德仁将满65岁。
> Finished chain.
----------- 最终答案 ----------- 到2025年6月10日,日本天皇德仁将满65岁。 |