使用 LangChain 的你的第一个工具型 AI 智能体
用 Python 构建一个小型 LangChain 数学智能体:初始化聊天模型,注册工具,让大语言模型选择要调用的函数,并观察多步骤的工具使用过程。
一个简短的 Python + LangChain 实践可以构建出一个类似计算器的智能体,它在需要时能够调用加法、减法、乘法、除法或平方根等辅助函数。
算术运算只是附带的。真正有价值的是观察大语言模型如何接收这些可调用的辅助函数,并决定在哪个步骤调用哪个辅助函数。
该智能体能够处理的示例问题:
将 25 乘以 4,再取 144 的平方根,最后将得到的结果乘以 5。
无需手动编写具体的计算步骤,只需注册多个辅助函数即可。模型会根据用户的表述从中选择合适的函数。
1. 初始化模型
首先需要构建聊天模型:
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-4o-mini")
目前还不存在类似智能体的结构——只有一個能够读写文本的模型。
2. 注册可调用的辅助函数
当智能体能够超越单纯的文本生成并调用应用程序功能时,它们便变得实用起来。
定义五个最基本的辅助函数:
from langchain.tools import tool
import math
@tool
def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
@tool
def subtract(a: float, b: float) -> float:
"""Subtract two numbers."""
return a - b
@tool
def multiply(a: float, b: float) -> float:
"""Multiply two numbers."""
return a * b
@tool
def divide(a: float, b: float) -> float:
"""Divide two numbers."""
if b == 0:
raise ValueError("Cannot divide by zero.")
return a / b
@tool
def square_root(a: float) -> float:
"""Calculate the square root of a number."""
if a < 0:
raise ValueError("Cannot calculate square root of a negative number.")
return math.sqrt(a)
使用@tool标记可将每个函数以智能体运行时能够理解的形式呈现出来。
有两个要素用于引导模型:
- 带注释的参数可指定所需的参数类型。
a: float
b: float
- 文档字符串会提供通俗易懂的描述,模型在判断相关性时会参考这些描述。
对于智能体工具而言,函数的叙述性描述属于控制界面的一部分,而非装饰内容。
"""Multiply two numbers."""
3. 连接智能体
将这些辅助函数绑定到模型上:
from langchain.agents import create_agent
agent = create_agent(
model=model,
tools=[
add,
subtract,
multiply,
divide,
square_root
],
)
这样一来,聊天模型就可以作为智能体来运行,而不仅仅是一个一次性回答工具。
典型步骤包括:
- 解析用户的意图
简而言之:
User
↓
Agent
↓
Should I use a tool?
↓
Choose tool
↓
Execute tool
↓
Get result
↓
Final response
多步骤问题可能会重复该循环。
4. 执行一次运行
只需一个简单的封装结构即可驱动其运行:
def run_agent(question: str):
"""Run the agent and print the execution trace."""
print(f"User: {question}")
result = agent.invoke({
"message": [("user", question)],
})
print("Agent:", result)
通过一个简单的问题来调用它:
run_agent("What is 25 multiplied by 4?")
注意这里并没有“调用multiply”这样的指令。
仅提供了辅助工具的列表。
根据表述及每个辅助工具的描述,模型判定乘法是合适的操作。
5. 连续使用多个辅助工具
尝试使用复合提示:
run_agent(
"Calculate the square root of 144 and multiply the result by 5."
)
需要执行两个操作。
其概念流程如下:
User:
Calculate √144 × 5
↓
Agent chooses square_root
↓
square_root(144)
↓
12
↓
Agent chooses multiply
↓
multiply(12, 5)
↓
60
↓
Final answer
那种循环——选择、调用、观察、再次选择——正是工具使用型智能体的核心所在。
应用代码无需预先编码完整的操作顺序。
模型可以根据剩余的辅助工具和对话状态推导出下一步该做什么。
6. 与普通大语言模型的对比
在没有工具的情况下,模型可能会直接输出“答案是60”这样的文本。
当有注册好的辅助工具时,它就可以将数值计算任务交给真正的函数来处理。
控制权的转移
仅文本路径:用户 → 模型 → 答案字符串
与之相对的是:
Tool-using agent
User
↓
LLM
↓
Choose tool
↓
Execute code
↓
Observe result
↓
LLM
↓
Answer
模型不再需要亲自执行所有的计算。
它只需提出“下一步应执行哪个操作”;具体有哪些操作以及如何执行则由应用程序决定。
7. 需要保护的边界
计算器只是一种教学工具而已。
这一稳健的设计思路在于将模型判断与执行权限分开。
自然语言理解与动作选择非常适合由大语言模型处理。
这些动作的实际执行则应在您可控的 Python 环境中完成。
模型可能会认为需要这种分离机制。
具体的分离实现及其带来的副作用由您的流程负责处理。
可以用领域特定的操作来替代那些简单的数学计算工具,例如:
get_customer()
search_transactions()
create_report()
send_email()
query_database()
get_weather()
create_ticket()
这样一来,同样的协调模式就开始具备生产级智能体设计的特征。
练习总结
通过几个模块的配合,我们构建出了一个能够:
- 理解自由形式的提问
- 从多个已注册的工具中选择合适的工具
- 正确传递参数
- 在单次会话中组合使用多个工具
- 将工具的输出反馈到后续的推理过程中
简而言之:这是一种能够选择并执行操作的LLM,而非仅能生成文本的模型。