第6节:智能体

1. 智能体可以做什么

用一句话概括,智能体是可以根据用户的要求,自主与环境交互,调用工具,并完成用户要求的应用程序。

如果进一步概括智能体的能力,可以分为一下几个步骤:

  1. 分析用户的请求或设定的目标。
  2. 决定使用哪个可用的工具来达成目标。
  3. 思考执行的顺序和每个工具的输入。
  4. 调用选定的工具并获取结果。
  5. 分析返回结果是否能达到目标,如果未达成,则重复步骤 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的工具文档open in new window,如果有工具使用需求,可以参考文档内容自行调用。

下面以一个“文件系统”工具为例写一个案例,这个案例暂时先不涉及大模型,仅仅是使用

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 的最终答案。