文章目录

前言

很多人刚接触大模型开发时,只会写固定流程的Chain(链式流程),但遇到需要动态判断、多分支任务的场景就束手无策。
比如一句需求:查北京明天天气,如果下雨就取消户外预约
固定Chain根本无法实现——流程取决于天气结果,代码没法提前写死分支。而Agent(智能体) 就是解决这类动态任务的核心方案。

本文基于LangChain完整Agent体系,用通俗语言拆解全部核心知识点:Agent核心原理、工具调用、MCP标准化工具、记忆管理、中间件、最佳实践,新手也能看懂。

一、什么是Agent?和Chain到底有什么区别?

1.1 Chain的局限:固定流水线,无法自主决策

Chain是开发者提前写死流程,所有步骤线性执行,路径完全固定:

用户输入 → 提示词模板 → LLM → 解析输出

举个例子:翻译工具Chain,永远只会执行「输入文本→翻译→输出」,中途不会产生任何分支判断。
一旦任务存在未知分支、条件判断、多轮工具调用,Chain直接失效。

1.2 Agent核心定义:让LLM拥有自主决策权

Agent = LLM大脑 + 自主决策 + 工具调用
核心逻辑转变:

  • Chain:你告诉AI怎么做,AI只负责执行(流程由人定义)
  • Agent:你只告诉AI要做什么,AI自己思考步骤、选择工具、调整方案(流程由LLM动态生成)

Agent会循环执行一套「感知→推理→行动」闭环,直到任务完成:

  1. 感知:接收用户提问/上一轮工具返回结果
  2. 推理:LLM自主判断下一步:要不要调用工具?调用哪个?传什么参数?
  3. 行动:执行工具,拿到结果再次进入感知;任务完成则直接输出答案

1.3 四大核心组件(通俗易懂版)

Agent由4个协作组件构成,最简Agent仅需LLM+Tools,记忆、规划属于增强能力:

组件 角色类比 核心作用
LLM(大脑) 总指挥 理解需求、拆分任务、每一步做决策,驱动整套流程
Tools(工具) 手脚 执行外部操作(查天气、搜索、计算、调API),LLM不能直接操作外部系统
Memory(记忆) 记事本 存储历史对话,多轮聊天不“失忆”,区分不同用户会话
Planning(规划) 思考逻辑 分两种模式:
1. ReAct边走边想(基础):每一步临时思考下一步
2. Plan-and-Execute全局规划(复杂任务):先出完整步骤清单再执行

重点:LangChain中Planning不是独立代码组件,而是内置在LLM推理与提示词里的能力,日常开发不用单独实例化。

1.4 Chain vs Agent 完整对比表

对比维度 Chain(链式) Agent(智能体)
流程控制权 开发者硬编码定义 LLM运行时自主决定
执行路径 线性、固定不变 循环、动态分支
工具调用 固定位置调用固定工具 按需选择,调用次数不固定
应对突发 无法处理预期外情况 根据工具结果灵活调整策略
适用场景 步骤固定、无判断的简单任务(翻译、摘要) 开放式、需要多步判断、动态操作(智能客服、自动化办公)
可预测性 极高,每次执行路径一致 较低,不同输入路径不同
开发难度 中等,需要设计工具、优化提示词

1.5 开发选择建议

  • 流程100%固定:优先Chain,简单稳定、开销低
  • 需要分支判断、多轮工具交互:必须用Agent
  • 两者可混用:Agent内部子流程可以封装Chain

二、工具定义与使用:Agent的“手脚”,底层是Function Calling

Agent不能直接操作外部系统,所有实操都依赖工具,工具底层依托大模型原生Function Calling能力。

2.1 Function Calling底层原理(核心必懂)

很多新手混淆工具调用逻辑,记住一句话:LLM只会选工具、写参数,不会真正执行工具,执行全靠本地代码
完整流程:

  1. 开发者定义工具(函数+描述+参数规范)
  2. LangChain自动转为JSON Schema,随提示词发给LLM
  3. LLM分析需求,输出工具调用指令(工具名+参数)
  4. 框架解析指令,本地运行对应函数
  5. 工具结果回传给LLM,LLM继续推理或输出最终回答

2.2 LangChain快速定义工具:@tool装饰器

不用手写复杂JSON Schema,@tool装饰器一键转换函数为Agent可用工具,三大关键点决定调用准确率:

  1. 函数名:动词+名词,语义清晰(get_weather而非tool1
  2. Docstring:详细说明工具用途、参数含义,相当于给LLM的说明书
  3. 参数类型注解:明确参数格式、约束,减少LLM传参错误

示例:基础天气工具

from langchain.tools import tool
@tool
def get_weather(city: str, date: str) -> str:
    """获取指定城市指定日期天气预报
    Args:
        city: 城市中文名称,如北京、上海
        date: 查询日期,格式YYYY-MM-DD
    """
    # 实际项目对接天气API
    return f"{city}{date}多云,局部小雨"

复杂参数:Pydantic模型约束
参数结构复杂时,用BaseModel精细化限制参数:

from pydantic import BaseModel, Field
class WeatherArgs(BaseModel):
    city: str = Field(description="城市名称")
    date: str = Field(description="日期YYYY-MM-DD")

@tool(args_schema=WeatherArgs)
def get_weather(city: str, date: str) -> str:
    """查询天气预报"""
    return f"{city}{date}天气晴朗"

2.3 一行创建Agent:create_agent

工具定义完成后,通过create_agent组装模型、工具、记忆、中间件,自动封装所有底层工具调用逻辑:

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model

# 1. 初始化LLM大脑
llm = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 2. 工具列表(自定义工具+第三方搜索工具)
tools = [get_weather, TavilySearch(max_results=3)]
# 3. 构建Agent
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是生活助手,按需调用工具回答用户问题,无工具则直接回复"
)

2.4 Agent两种调用方式

  1. invoke() 一次性调用:等待全部推理、工具执行完毕,统一返回结果,适合后台任务
  2. stream() 流式调用:实时打印每一步思考、工具调用、返回结果,调试必备,前端聊天界面首选

2.5 调试利器:LangSmith

Agent流程动态不可控,报错难定位,开启LangSmith可视化追踪:

import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "你的密钥"
os.environ["LANGSMITH_PROJECT"] = "agent调试项目"

平台可查看每一轮LLM输入输出、工具参数、循环次数,快速定位「选错工具、参数错误、无限循环」问题。

三、MCP协议:AI工具界的Type-C,标准化接入外部服务

3.1 为什么需要MCP?

本地@tool工具适合简单业务,但对接第三方服务(12306、GitHub、数据库)存在巨大痛点:
每个外部系统接口规范、认证、加密逻辑完全不同,接入一个就要写一套适配代码,无法复用。

MCP(Model Context Protocol,模型上下文协议) 统一工具通信标准,类比USB-C:

  • 无MCP:查火车票REST、查数据库JDBC、GitHub GraphQL,三套适配代码
  • 有MCP:所有工具服务统一协议,一套客户端代码对接全部服务,一次开发全平台复用

3.2 MCP三层架构

  1. MCP Host:你的LangChain Agent程序(客户端宿主)
  2. MCP Client:Host内置通信客户端,负责和服务端收发指令
  3. MCP Server:独立部署的工具服务,暴露工具、资源、提示词模板

3.3 两种传输模式,适配不同场景

传输方式 通信原理 使用场景
Stdio标准输入输出 本地进程间通信,不走网络端口 本地开发调试、本机工具
Streamable HTTP流式HTTP 网络远程通信 云端部署、多客户端共享工具服务

3.4 MCP Server不止提供工具

MCP服务端可输出三类能力,统一被Agent加载:

  1. @mcp.tool():可执行操作(查车票、计算),对应本地@tool
  2. @mcp.resource():只读静态资源(企业手册、日志),类似虚拟文件
  3. @mcp.prompt():预定义提示词模板,第三方服务内置最优话术,无需手写Prompt

3.5 LangChain集成MCP

通过MultiServerMCPClient同时连接多个本地/远程MCP服务,所有工具自动转为LangChain标准工具,对LLM完全透明,分不清本地工具和MCP远程工具:

client = MultiServerMCPClient({
    # 本地Stdio服务
    "本地计算工具": {"transport": "stdio", "command": "python", "args": ["mcp_server.py"]},
    # 远程HTTP服务
    "12306票务服务": {"transport": "streamable_http", "url": "https://xxx/mcp"}
})
# 自动获取全部工具
tools = await client.get_tools()

3.6 本地工具 vs MCP工具选型

维度 本地@tool工具 MCP远程工具
部署位置 主项目代码内 独立Server进程,可单独部署
复用性 仅当前项目可用 全平台、多项目共享
维护成本 和主项目耦合更新 独立迭代、独立运维
适用场景 简单业务逻辑、短期项目 通用公共工具、第三方服务、跨团队复用

四、记忆管理:解决Agent“失忆”,多会话隔离

4.1 默认痛点:无记忆,每次对话清零

不配置记忆时,每次invoke都是独立会话,Agent完全遗忘上一轮对话:

用户:我叫张三
Agent:你好张三
用户:我叫什么?
Agent:不清楚你的名字

4.2 核心解决方案:Checkpointer

记忆底层由Checkpointer实现,执行逻辑:

  1. 对话结束:自动存储本轮全部消息
  2. 新一轮对话:加载历史消息拼接至输入,LLM读取完整上下文

最简内存记忆示例:

from langgraph.checkpoint.memory import InMemorySaver
# 创建内存存储器(程序重启数据丢失)
checkpointer = InMemorySaver()
# 创建Agent时传入
agent = create_agent(llm, tools, checkpointer=checkpointer)

4.3 Thread ID:多用户会话隔离

一个Agent同时服务多个用户,依靠thread_id区分独立会话,不同ID历史完全隔离互不干扰:

# 用户张三会话
agent.invoke(input, config={"configurable": {"thread_id": "user_zhangsan"}})
# 用户李四全新会话,看不到张三聊天记录
agent.invoke(input, config={"configurable": {"thread_id": "user_lisi"}})

4.4 记忆的致命缺陷:上下文无限膨胀

多轮对话后消息列表持续变长,带来两个问题:

  1. Token消耗暴增,调用成本上涨
  2. 超出模型上下文窗口,直接报错

解决方案:下一章消息压缩中间件

五、Agent中间件:执行流程拦截器,解决记忆、安全问题

中间件是嵌入Agent执行链路的拦截器,可在LLM调用前后、工具执行前后介入处理,支持叠加多个中间件。

5.1 两种高频实用中间件

1. SummarizationMiddleware 消息压缩(解决长对话)

当消息数量/Token达到阈值,自动把老旧历史压缩为一段摘要,大幅减少上下文长度:

from langchain.agents.middleware import SummarizationMiddleware
summary_mid = SummarizationMiddleware(
    model=llm,
    trigger=("tokens", 3000) # Token超过3000自动压缩
)

触发规则三选一:按消息条数、按上下文占比、按Token绝对值。

2. HumanInTheLoopMiddleware 人工审核(高危操作安全兜底)

转账、删除数据等高风险工具调用前,拦截Agent执行,暂停流程等待人工确认,防止AI误操作:

hitl_mid = HumanInTheLoopMiddleware(
    interrupt_on={
        "transfer_money": True, # 转账需要审核
        "get_weather": False # 查天气无需审核
    }
)

执行流程:AI触发高危工具→中间件拦截暂停→人工批准/拒绝→继续执行或取消操作。

5.2 中间件使用方式

创建Agent时传入中间件列表,按顺序执行:

agent = create_agent(
    model=llm,
    tools=tools,
    checkpointer=checkpointer,
    middleware=[summary_mid, hitl_mid] # 叠加多个中间件
)

六、Agent最佳实践:避坑指南,提升稳定性

6.1 工具设计五大黄金原则

  1. 单一职责:一个工具只做一件事,不要合并多个功能(不要handle_weather_and_calendar
  2. 描述详尽:Docstring写清用途、参数格式、使用场景,LLM依赖描述判断调用时机
  3. 参数约束明确:标注格式、取值范围,减少传参错误
  4. 错误友好:工具报错返回提示,而非原生异常栈,方便LLM修正参数重试
  5. 幂等安全:查询类工具优先,修改/创建类工具增加校验,避免重复执行产生脏数据

6.2 系统提示词优化技巧

好的提示词=角色定位+工作流程+约束条件+输出规范,拒绝模糊话术:

# 优质提示词模板
你是专业出行助手,工作流程:
1. 先查询目的地天气
2. 根据天气判断是否需要预约户外行程
3. 下雨则调用取消预约工具,不下雨直接回复天气
约束:不编造天气数据,所有信息必须调用工具获取,输出简洁口语化文字

6.3 性能优化方案

  1. 精简工具列表:只加载当前任务必需工具,减少LLM选择开销
  2. 开启消息压缩中间件,降低Token消耗
  3. 工具返回结果精简,减少循环调用次数
  4. 使用ainvoke异步调用,支持并发处理多用户请求

七、完整知识体系总结 & 技术栈定位

7.1 LangChain四层技术栈(自底向上)

  1. 基础层 Model I/O:模型调用、提示词、输出解析(只能纯文字对话)
  2. 组合层 Chains:固定线性流程编排,无自主决策
  3. 知识层 RAG:私有文档检索,给模型补充外部知识
  4. 智能层 Agents:自主决策、工具调用、记忆、中间件(本文核心)

进阶:LangGraph,用于多Agent协作、复杂分支、状态管理。

7.2 核心知识点复盘

  1. Agent核心:LLM自主决定流程,循环感知-推理-行动,区别于固定Chain
  2. 工具底层:Function Calling,@tool快速封装本地工具
  3. MCP:标准化远程工具协议,像USB一样即插即用
  4. 记忆:Checkpointer+Thread ID实现多轮会话、多用户隔离
  5. 中间件:消息压缩、人工审核,解决长上下文与安全风险
  6. 落地关键:规范工具设计、优化提示词、借助LangSmith调试

7.3 常见问题解答

  1. Chain和Agent怎么选?
    流程固定用Chain;需要动态判断、多工具分支用Agent,二者可嵌套。
  2. RAG和Agent可以结合吗?
    完全可以,把文档检索封装成工具,Agent自主按需查询知识库。
  3. 什么时候需要LangGraph?
    多智能体协作、复杂分支循环、精细状态控制场景,create_agent能力不足时使用。

八、学习落地建议

  1. 动手小项目:搭建简易智能客服Agent,融合本地工具+MCP工具+记忆+压缩中间件
  2. 调试优先:开发全程使用stream流式输出+LangSmith追踪,快速定位工具调用异常
  3. 生态拓展:学习社区MCP工具服务,快速给Agent增加搜索、数据库、办公系统能力
  4. 进阶学习:LangGraph状态编排,实现多Agent协同复杂业务系统

更多推荐