03 — Agent 智能体与 LangGraph 知识点总结
面向人群:AI 初学者 / 大模型应用开发岗位候选人 学习目标:从零理解 Agent 的原理、实现方式和企业落地实践 前置知识:了解 LLM 基本调用、Prompt 工程
目录
一、Agent 基础概念
1.1 什么是 Agent
Agent(智能体) 是\”LLM + 工具 + 决策循环\”的组合体。它不止会\”说话\”,还会\”行动\”。
| 能力范围 | 只能生成文本 | 能调用工具、访问数据库、执行代码 |
| 决策方式 | 一次回答结束 | 多轮思考-行动循环 |
| 对外交互 | 无(纯文本输出) | 有(通过工具操作外部系统) |
| 典型输出 | “北京今天可能会下雨” | 调用天气API获取实时数据后回答 |
Agent 的核心三要素:
┌─────────────┐
│ LLM (大脑) │ ← 推理决策
└──────┬──────┘
│ 决策
┌────────┴────────┐
│ │
┌────▼────┐ ┌────▼────┐
│ Tool (手) │ │ Memory │ ← 记忆
└──────────┘ └─────────┘
1.2 ReAct 模式:Reason → Act → Observe 循环
ReAct = Reasoning(推理) + Acting(行动),是 Agent 最核心的工作模式。
用户提问 \”北京今天天气怎么样?\”
│
▼
┌─ 步骤1: 推理 (Reason) ─────────────────────┐
│ LLM 思考:\”用户想知道北京天气, │
│ 我需要调用 get_weather 工具\” │
└────────────────────────────────────────────┘
│
▼
┌─ 步骤2: 行动 (Act) ────────────────────────┐
│ 调用工具 get_weather(city=\”北京\”) │
│ 返回结果:\”晴,25°C\” │
└────────────────────────────────────────────┘
│
▼
┌─ 步骤3: 观察 (Observe) ────────────────────┐
│ LLM 看到工具返回的数据 │
│ 思考:\”北京是晴天,25度\” │
└────────────────────────────────────────────┘
│
▼
┌─ 步骤4: 最终回答 ──────────────────────────┐
│ \”北京今天天气晴朗,气温25°C,适合外出活动\” │
└────────────────────────────────────────────┘
循环的关键:如果 LLM 认为还需要更多信息,它会再次调用工具(循环),直到所有信息足够回答用户为止。
1.3 Agent vs 普通 LLM 的代码对比
# ===== 普通 LLM =====
model.invoke(\”北京今天天气怎么样?\”)
# 输出: \”我无法获取实时天气数据,建议你查看天气预报APP\”
# ===== Agent =====
@tool
def get_weather(city: str) –> str:
\”\”\”查询指定城市的天气。\”\”\”
return {
\”北京\”: \”晴,25°C\”, \”上海\”: \”多云,28°C\”}.get(city, \”暂无数据\”)
agent = create_agent(model=model, tools=[get_weather],
system_prompt=\”你是一个有用的助手\”)
agent.invoke({
\”messages\”: [HumanMessage(\”北京今天天气怎么样?\”)]})
# 输出: \”北京今天天气晴朗,气温25°C,适合外出活动\”
1.4 生活化比喻
Agent = 餐厅服务员
- 顾客点餐(用户输入)
- 服务员判断需要什么(LLM 推理)
- 去厨房/吧台取餐(调用工具)
- 端给顾客(输出答案)
- 复杂订单多跑几趟(多次循环)
普通 LLM = 只会说话的顾问
- 能给出建议,但无法实际操作
- 说\”你应该查一下天气预报\”,但自己不会查
二、Tool 工具定义
2.1 什么是 Tool
Tool(工具) 是 Agent 与外部世界交互的桥梁。纯 LLM 只能\”说\”——生成文字;有了 Tool 就能\”做\”——调用外部函数。Tool = 给 AI 配的工具箱。
2.2 @tool 装饰器基础
LangChain 提供了最简洁的工具定义方式——@tool 装饰器:
from langchain_core.tools import tool
@tool
def get_weather(city: str) –> str:
\”\”\”查询指定城市的天气信息。
Args:
city: 城市名称,如\”北京\”、\”上海\”
\”\”\”
weather_db = {
\”北京\”: \”晴,25°C\”, \”上海\”: \”多云,28°C\”, \”广州\”: \”小雨,30°C\”}
return weather_db.get(city, f\”暂无 {
city} 的天气数据\”)
# 查看工具元信息
print(f\”工具名: {
get_weather.name}\”) # get_weather
print(f\”描述: {
get_weather.description}\”) # 查询指定城市的天气信息
print(f\”参数: {
get_weather.args}\”) # {\’city\’: {\’title\’: \’City\’, \’type\’: \’string\’}}
# 直接调用(不需要LLM)
result = get_weather.invoke({
\”city\”: \”北京\”})
关键点:
- 函数的文档字符串(docstring) 会被 LLM 读取,帮助 LLM 决定何时调用该工具
- 函数的类型注解 会被自动提取为参数 Schema
- @tool 装饰器自动将函数转换为 LLM 可调用的工具对象
2.3 工具描述的重要性
LLM 通过工具的描述来决定是否调用它。描述写得越清楚,LLM 就越能正确地使用工具。
# ❌ 不好的描述
@tool
def calc(x: str) –> str:
\”\”\”计算\”\”\”
return str(eval(x))
# ✅ 好的描述
@tool
def calculate(expression: str) –> str:
\”\”\”执行数学计算。
当你需要做加减乘除、幂运算、三角函数等数学计算时使用。
Args:
expression: 数学表达式,如 \”3 + 5 * 2\”, \”sqrt(16)\”, \”2 ** 10\”
\”\”\”
try:
return str(eval(expression, {
\”__builtins__\”: {
}}, {
}))
except Exception as e:
return f\”计算错误: {
e}\”
面试重点:工具描述是 Agent 正确性的关键。描述模糊 = LLM 不会用该工具 = 工具形同虚设。
2.4 bind_tools() 工具注册
工具定义好后,需要通过 bind_tools() 注册到模型:
# 1. 定义工具
@tool
def get_weather(city: str) –> str:
\”\”\”查询天气\”\”\”
...
@tool
def calculator(expression: str) –> str:
\”\”\”计算数学表达式\”\”\”
...
# 2. 注册到模型
model = ChatOllama(model=\”qwen3.5:2b\”)
model_with_tools = model.bind_tools([get_weather, calculator])
# 3. 现在模型知道有哪些工具可用
# 当用户问\”北京天气怎么样\”,model_with_tools 会返回 tool_calls
response = model_with_tools.invoke(\”北京天气怎么样?\”)
print(response.tool_calls) # [{\’name\’: \’get_weather\’, \’args\’: {\’city\’: \’北京\’}, \’id\’: \’…\’}]
2.5 复杂参数与 Pydantic Schema
当工具参数比较复杂时,可以用 Pydantic 模型定义参数 Schema,自带类型验证:
from pydantic import BaseModel, Field
from typing import Literal
class WeatherInput(BaseModel):
\”\”\”天气查询参数。\”\”\”
city: str = Field(description=\”城市名称\”)
units: Literal[\”celsius\”, \”fahrenheit\”] = Field(
default=\”celsius\”, description=\”温度单位\”
)
@tool(args_schema=WeatherInput)
def get_weather(city: str, units: str = \”celsius\”) –> str:
\”\”\”查询指定城市的天气。\”\”\”
temp = 22 if units == \”celsius\” else 72
unit = \”°C\” if units == \”celsius\” else \”°F\”
return f\”{
city} 当前温度: {
temp}{
unit}\”
2.6 企业实践:客服 Agent 的多工具设计
在实际企业中,一个客服 Agent 可能需要多个工具协同工作:
@tool
def query_order(order_id: str) –> str:
\”\”\”查询订单状态。\”\”\”
# 调用订单系统 API
return f\”订单 {
order_id} 状态: 已发货\”
@tool
def query_logistics(express_no: str) –> str:
\”\”\”查询物流信息。\”\”\”
# 调用物流平台 API
return f\”快递 {
express_no} 当前位置: 北京分拣中心\”
@tool
def initiate_return(order_id: str, reason: str) –> str:
\”\”\”发起退换货申请。\”\”\”
# 调用售后系统 API
return f\”退换货申请已提交,订单 {
order_id}\”
@tool
def get_support_hours() –> str:
\”\”\”查询客服工作时间。\”\”\”
return \”人工客服工作时间: 周一至周日 9:00-21:00\”
# 注册所有工具
tools = [query_order, query_logistics, initiate_return, get_support_hours]
企业中 Agent 工具的设计原则:
三、Agent 实现方式
3.1 方式1:model.bind_tools() + 手动循环
最底层的方式,手动控制思考-行动循环:
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage, ToolMessage
@tool
def add(a: int, b: int) –> int:
\”\”\”计算两个数的和\”\”\”
return a + b
@tool
def multiply(a: int, b: int) –> int:
\”\”\”计算两个数的乘积\”\”\”
return a * b
tools = [add, multiply]
tools_by_name = {
t.name: t for t in tools}
model = ChatOllama(model=\”qwen3.5:2b\”)
model_with_tools = model.bind_tools(tools)
# 手动 ReAct 循环
messages = [HumanMessage(content=\”(3 + 4) × 5 等于多少?\”)]
while True:
response = model_with_tools.invoke(messages)
messages.append(response)
# 检查是否需要调用工具
if not hasattr(response, \’tool_calls\’) or


