第07章:Agent 开发实战

2 阅读6分钟

第07章:Agent 开发实战

版本:LangChain v1.3.7 | 讲师:汤姆小白


1. Agent 概述

1.1 什么是 Agent

Agent(智能体)是具有自主决策能力的 AI 应用。与简单的"一问一答"不同,Agent 会自己思考、选择工具、多步推理,直到完成目标任务。

Chain:固定流程,AB → C
Agent:自主决策,根据情况动态选择下一步做什么

1.2 Agent 的核心循环

用户输入 → 模型思考 → 需要工具? → 是 → 执行工具 → 回到思考
                         ↓
                         否 → 输出最终答案

这个"思考-行动-观察"的循环是 Agent 的本质。每次循环,LLM 都会决定:给出最终答案,还是调用工具获取更多信息。


2. create_agent:统一入口

2.1 最简 Agent

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool

# 1. 定义工具
@tool
def get_weather(city: str) -> str:
    """查询指定城市的天气"""
    weather_data = {
        "北京": "晴,28°C",
        "上海": "多云,32°C",
        "深圳": "阵雨,26°C",
    }
    return weather_data.get(city, f"未找到 {city} 的天气数据")

# 2. 创建 Agent
model = init_chat_model("openai:gpt-4o-mini")
agent = create_agent(
    model=model,
    tools=[get_weather],
    system_prompt="你是一个有用的天气助手,帮助用户查询天气信息。",
)

# 3. 使用 Agent
result = agent.invoke({
    "messages": [{"role": "user", "content": "北京今天天气怎么样?"}]
})
print(result["messages"][-1].content)

2.2 create_agent 参数

参数类型说明
modelBaseChatModel模型实例或字符串(自动用 init_chat_model 初始化)
toolsList[BaseTool]工具列表
system_promptstr系统提示词,定义 Agent 角色
middlewareList中间件列表(见第3节)
checkpointerCheckpointer持久化检查点(见第06章 LangGraph)

2.3 完整工具调用示例

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_core.tools import tool
import math

@tool
def calculator(expression: str) -> str:
    """执行数学计算,支持 + - * / ** sqrt() 等运算"""
    try:
        result = eval(expression, {"__builtins__": {}}, {"sqrt": math.sqrt})
        return f"计算结果: {result}"
    except Exception as e:
        return f"计算出错: {e}"

@tool
def word_count(text: str) -> str:
    """统计文本的字数"""
    return f"共 {len(text)} 个字符"

# 创建 Agent
model = init_chat_model("openai:gpt-4o-mini")
agent = create_agent(
    model=model,
    tools=[calculator, word_count],
    system_prompt="你是数学和文字助手,能计算和统计。",
)

# 测试
result = agent.invoke({
    "messages": [{"role": "user", "content": "计算 2 的 10 次方是多少?"}]
})
print(result["messages"][-1].content)

3. Middleware 中间件体系

3.1 什么是 Middleware

Middleware 是 Agent 的"切面拦截器",在 Agent 执行的各个阶段插入自定义逻辑。

Agent 执行 = 内置逻辑 + Middleware 拦截层

类似 Web 框架的中间件——在请求处理链中插入鉴权、日志、限流等逻辑。

3.2 六大拦截点

拦截点装饰器触发时机适用场景
Agent 执行前@before_agent收到用户请求,Agent 启动前日志记录、权限校验
模型调用前@before_model每次调用模型之前修改系统提示词、注入上下文
包装模型调用@wrap_model_call模型调用过程修改请求/响应、动态选模型
模型调用后@after_model每次模型调用完成日志收集、输出校验
包装工具调用@wrap_tool_call工具调用过程监控工具调用、权限控制
Agent 结束后@after_agentAgent 执行完成统计信息、清理资源

3.3 代码示例

from langchain.agents import create_agent
from langchain.agents.middleware import (
    before_agent, after_agent,
    before_model, after_model,
    wrap_model_call, wrap_tool_call,
)

# before_model:动态修改系统提示词
@before_model
def inject_user_context(state, runtime):
    """在每次模型调用前注入用户上下文"""
    system_msg = state["messages"][0]
    system_msg.content += "\n当前时间:2026年6月12日"
    return None

# wrap_model_call:记录模型调用耗时
@wrap_model_call
def log_model_call(request, handler):
    import time
    start = time.time()
    result = handler(request)
    elapsed = time.time() - start
    print(f"[模型调用] 耗时: {elapsed:.2f}s")
    return result

# wrap_tool_call:监控工具调用
@wrap_tool_call
def monitor_tools(request, handler):
    print(f"[工具调用] {request.tool_call['name']}")
    print(f"[参数] {request.tool_call['args']}")
    result = handler(request)
    print(f"[结果] {result}")
    return result

# 注册中间件
agent = create_agent(
    model="openai:gpt-4o-mini",
    tools=[...],
    system_prompt="你是智能助手",
    middleware=[
        inject_user_context,
        log_model_call,
        monitor_tools,
    ],
)

3.4 中间件执行顺序(洋葱模型)

before_agent  →  before_model  →  wrap_model_call(模型)  →  after_model
                                  ↓
                             wrap_tool_call(工具)
                                  ↓
                             before_model  →  ...循环...
                                  ↓
                             after_agent

多个同类型中间件按注册顺序依次执行,wrap_* 类型的"后置"部分按反向顺序执行。


4. Context Engineering(上下文工程)

4.1 核心理念

"上下文工程是以正确的格式提供正确的信息和工具,以便 LLM 能完成任务。这是 AI 工程师的首要工作。"

上下文工程解决 Agent 三大实际问题:

  1. 上下文过长:历史消息越多,推理越慢、越容易出错
  2. 信息杂乱:无关信息干扰 LLM 判断
  3. 超出 Token 限制:对话太长时需要裁剪

4.2 上下文管理策略

策略1:滑动窗口
@before_model
def sliding_window(state, runtime, max_messages=20):
    """只保留最近 N 条消息"""
    state["messages"] = state["messages"][-max_messages:]
策略2:动态摘要
@before_model
def dynamic_summary(state, runtime):
    """当消息超过阈值时,自动摘要早期对话"""
    if len(state["messages"]) > 30:
        # 保留前10条(系统提示+初始上下文)
        # 摘要中间部分
        # 保留最后10条(最近的对话)
        early = state["messages"][:10]
        middle = state["messages"][10:-10]
        recent = state["messages"][-10:]
        
        # 用模型做摘要
        summary = model.invoke([
            {"role": "system", "content": "请用一段话总结以下对话"},
            *middle,
        ])
        
        state["messages"] = [
            *early,
            {"role": "system", "content": f"对话历史摘要: {summary.content}"},
            *recent,
        ]
策略3:工具输出截断
@wrap_tool_call
def truncate_tool_output(request, handler, max_chars=2000):
    """截断过长的工具输出"""
    result = handler(request)
    if isinstance(result, str) and len(result) > max_chars:
        result = result[:max_chars] + f"\n... (已截断,原长{len(result)}字符)"
    return result

5. Agent 流式输出

# 逐条消息流式输出
for chunk in agent.stream(
    {"messages": [{"role": "user", "content": "用Python写一个快速排序"}]},
    stream_mode="values",
):
    if "messages" in chunk and chunk["messages"]:
        last_msg = chunk["messages"][-1]
        role = last_msg.get("role", "unknown")
        content = last_msg.get("content", "")
        
        if isinstance(content, str) and content:
            print(f"[{role}] {content}")

6. Agent 类型速览

类型适用场景LangGraph 节点数
ReAct通用任务(create_agent 默认)model + tools
Tool Calling多工具选择调用model + tools
Multi-Agent多 Agent 协作多个 agent 节点
Human-in-the-Loop需要人工审批model + tools + interrupt

7. Agent vs Chain 对比

维度ChainAgent
执行方式固定流程自主决策
工具调用预设动态选择
循环能力多轮思考-行动
灵活性
复杂度简单复杂
适用场景明确的任务流水线开放式任务

本章小结

概念作用
create_agent一行代码创建 Agent
Middleware6 大拦截点,切面编程
Context Engineering管理上下文窗口、自动摘要
流式输出实时监控 Agent 思考过程

Agent 的本质:让 LLM 在"思考→行动→观察"中自主循环,直到完成任务。create_agent 是最高效的入口,Middleware 是实现定制化最灵活的武器。