第6节:智能体
1. 智能体可以做什么
用一句话概括,智能体是可以根据用户的要求,自主与环境交互,调用工具,并完成用户要求的应用程序。
如果进一步概括智能体的能力,可以分为一下几个步骤:
- 分析用户的请求或设定的目标。
- 决定使用哪个可用的工具来达成目标。
- 思考执行的顺序和每个工具的输入。
- 调用选定的工具并获取结果。
- 分析返回结果是否能达到目标,如果未达成,则重复步骤 2-4步骤,直到目标完成或达到停止条件。
看了上述概念,大概率也没办法完全理解概念的意思,不要紧,看完本节的内容,就知道智能体到第时如何实现上面步骤的了。
2. 工具
智能体的一个重要能力就是可以自主调用工具,那么有那些工具可以调用呢,这里可以分为langchain内置工具,自定义工具,以及第三方工具。
自定义工具
from langchain_core.tools import tool
@tool
def computy(a: int, b: int) -> int:
"""一个简单的工具,用于计算两个整数的乘积。"""
return a * b
result = computy.invoke({"a": 5, "b": 4})
print(result)
langchain内置工具
LangChain 提供了许多可以直接使用的内置工具,通常在 langchain_community.tools
中。使用工具需要先安装依赖:
pip install langchain-community
这里是langchain的工具文档,如果有工具使用需求,可以参考文档内容自行调用。
下面以一个“文件系统”工具为例写一个案例,这个案例暂时先不涉及大模型,仅仅是使用
from langchain_openai import ChatOpenAI;
from langchain_community.agent_toolkits import FileManagementToolkit
from dotenv import load_dotenv
import os;
from langchain.agents import initialize_agent,AgentType
load_dotenv()
tookKit = FileManagementToolkit(
root_dir = "D:/test"
)
tools = tookKit.get_tools();
llm = ChatOpenAI(
model=os.getenv("DEEPSEEK_MODEL"),
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_API_BASE")
)
agent = initialize_agent(
tools,
llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)
response = agent.run("请创建一个名为'notes.txt'的文件,并在其中写入'这是我的笔记:今天天气晴朗,适合散步。'")
print(response)
自定义工具
from langchain_core.tools import tool
@tool
def custom_multiplier(a: int, b: int) -> int:
"""一个简单的工具,用于计算两个整数的乘积。"""
return a * b
result = custom_multiplier.invoke({"a": 5, "b": 4})
print(result)
langchain中的Agent
一个典型的 Agent 由以下几个关键部分组成:
- 模型:负责思考
- Tools: Agent 可以使用的外部功能,放在一个列表中。
- 提示词:用于指导模型如何扮演 Agent 的角色、如何思考、如何使用工具以及如何格式化其输出。
- AgentExecutor: 负责实际运行 Agent 的决策循环。它接收用户输入,调用工具,将结果返回给 Agent,并重复此过程,直到 Agent 给出最终答案。
让Agent根据要求调用工具
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.prompts import ChatPromptTemplate
#引入占位符,在Agent思考的时候用来存储信息
from langchain_core.prompts.chat import MessagesPlaceholder
import os;
# 1. 使用 @tool 装饰器定义工具函数
@tool("AddNumbers") # 工具名称
def add_numbers(a: float, b: float) -> float:
"""计算两个数字的和。输入应为两个数字(如:{'a': 3, 'b': 5})"""
return a + b
@tool("SubtractNumbers")
def subtract_numbers(a: float, b: float) -> float:
"""计算两个数字的差(a减b)。输入应为两个数字(如:{'a': 10, 'b': 3})"""
return a - b
# 2. 将工具放入工具集(可以放多个工具)
tools = [add_numbers, subtract_numbers]
llm = ChatOpenAI(
model=os.getenv("DEEPSEEK_MODEL"),
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_API_BASE")
)
# 3. 构建提示词(关键:明确输入格式)
prompt = ChatPromptTemplate([
("system", "你是一个能使用工具的助手。根据问题判断是否需要调用工具,如需调用,严格按照工具要求的格式传递参数。"),
("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad")
])
#在 Agent 运行过程中,它需要记录自己的思考步骤、中间结果和工具调用过程。agent_scratchpad 就是用来存储这些临时思考内容的特殊变量。Agent 会将 "需要调用什么工具"、"传入什么参数" 等思考过程写入 agent_scratchpad。工具的返回结果(Observation)也会被添加到 agent_scratchpad 中,帮助 Agent 继续推理。
# 4. 初始化Agent(代理),连接LLM和工具
agent = create_tool_calling_agent(
llm=llm,
tools=tools,
prompt=prompt
)
# 5. 使用Agent调用工具解决问题
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
verbose=True # 显示详细过程
)
# 6. 正确调用:通过字典传递input参数(关键!)
result = agent_executor.invoke({"input": "计算10加上20的结果"})
print(result)
Agent 执行器 (AgentExecutor)
AgentExecutor 是运行 Agent 的核心。它编排了整个"思考 -> 行动 -> 观察"的循环。
关键参数:
agent
: 由工厂函数创建的 Agent 逻辑 (Runnable)。tools
: Agent 可以使用的工具列表。memory
(可选): 用于保持对话状态的 Memory 对象。verbose=True
: 打印详细的执行过程(思考、动作、观察等),非常有助于调试。max_iterations
: 限制 Agent 的最大思考/行动轮数,防止无限循环。handle_parsing_errors=True
: 尝试处理 Agent 输出格式错误的情况。
调用:
- 使用
executor.invoke({"input": "你的问题"})
来启动 Agent。 - AgentExecutor 会处理中间步骤,最终返回 Agent 的最终答案。