上篇:LangChain Agent 智能体从入门到实战(一)—— 概念、工具定义与 MCP 协议

上篇:LangChain Agent 智能体从入门到实战(一)—— 概念、工具定义与 MCP 协议

从“固定流程”到“自主决策”,让 LLM 自己决定下一步做什么。

在前面的课程中,我们学会了用 Chain(链)来编排固定的 LLM 调用流程。但现实世界的问题往往是开放的、动态的——你无法预先知道用户会问什么,也无法提前写好所有分支逻辑。

Agent(智能代理)应运而生。它把 LLM 当作“大脑”,让模型自己决定调用哪些工具、按什么顺序执行,直到完成任务。本文将带你理解 Agent 的核心思想,学会用@tool定义工具,并通过 MCP 协议接入外部服务,最终构建出第一个可用的 Agent。


一、Agent 是什么?为什么需要它?

1.1 从 Chain 到 Agent

Chain 的工作方式是预先定义好一条固定的处理流程,输入数据按顺序流经每一步,最终得到输出。这适合翻译、摘要等确定性任务。

但有些任务无法预知路径。比如:

“帮我查查北京明天会不会下雨,如果下雨,帮我取消明天的户外预约。”

要完成这个任务,程序需要:

  1. 先查天气 API;

  2. 根据结果(下雨/不下雨)判断;

  3. 如果下雨,再调用日程 API 取消预约;如果不下雨,直接回复。

步骤 2 和 3 在编写代码时无法确定。你不能硬编码成一条 Chain,因为每次用户输入不同,路径也不同。

Agent 的核心思想:把 LLM 当作大脑,让它自己决定下一步做什么。

Chain:开发者编排流程,LLM 负责执行 → “你告诉它怎么做”
Agent:LLM 自主编排流程,工具负责执行 → “你告诉它要做什么,它自己想怎么做”

1.2 核心组件与工作机制

Agent 有四大核心组件,但并非每个都必须具备。最简单的 Agent 只需要LLM + Tools即可工作。

组件角色说明
① LLM(大脑)理解意图,做出每一步决策中枢驱动
② Tools(工具)执行 LLM 的决策,与外部世界交互LLM“想”,工具“做”
③ Memory(记忆)存储上下文,让 Agent“记住”对话历史为决策提供历史信息
④ Planning(规划)分解复杂任务为可执行步骤隐含在推理过程和提示词中

工作机制:Agent 通过“感知 → 推理 → 行动”的循环来逐步完成任务。每轮循环,LLM 都会判断“任务完成了吗?”,如果没完成就继续调用工具、观察结果、再推理,直到给出最终答案。

以“查天气并取消预约”为例:

  • 第 1 轮:LLM 推理 → 需要查天气 → 调用get_weather→ 返回“小雨”

  • 第 2 轮:LLM 推理 → 明天下雨,需要取消预约 → 调用cancel_appointment→ 返回“已取消”

  • 第 3 轮:LLM 推理 → 任务完成 → 直接回复用户

整个过程中,没有任何代码预先规定“先查天气再取消预约”。执行路径是 LLM 动态决定的

1.3 什么时候用 Agent?

对比维度ChainAgent
谁决定流程开发者在代码中预定义LLM 在运行时自主决定
执行路径线性的、固定的循环的、动态的
工具调用在固定位置调用固定工具LLM 按需选择,调用次数不定
适合任务结构明确、步骤固定开放式、需要判断和决策
开发复杂度较高

实际建议:任务流程固定用 Chain(简单可靠),任务需要动态判断和多步决策时用 Agent。


二、工具定义:让 Agent 拥有“手脚”

Agent 的工具是它唯一能与外部世界交互的通道。LLM 负责“想”,工具负责“做”。工具的描述写得好不好,直接决定了 LLM 能不能正确地选择和调用它

2.1 工具调用的本质(Function Calling)

当我们给 Agent 配置工具时,实际发生的事情是:

  1. 你定义工具(函数名 + 参数说明 + 功能描述);

  2. LangChain 将工具信息转换成 JSON Schema,随提示词发给 LLM;

  3. LLM 阅读工具描述,决定“要调用哪个工具、传什么参数”;

  4. LLM 返回“工具调用指令”(不是执行,而是指令);

  5. LangChain 框架接收指令,在本地执行对应的函数;

  6. 执行结果返回给 LLM,LLM 继续推理。

关键理解:LLM 自身不能执行任何工具,它只是“调度员”。真正执行的是你的代码。

2.2 LangChain 的 @tool 装饰器

LangChain 提供@tool装饰器,只需写一个普通 Python 函数,加类型注解和 docstring,LangChain 会自动生成 JSON Schema。

python

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} 天气多云,有下雨的可能性。"

三个影响 LLM 调用准确性的关键点

要素作用写法建议
函数名LLM 初步判断工具用途用清晰的动词+名词,如get_weather
docstringLLM 理解工具具体功能写清楚“做什么”,越具体越好
参数类型注解LLM 决定传什么值每个参数都要有类型注解和说明

当参数复杂时,可以用 Pydantic 模型定义参数结构:

python

from pydantic import BaseModel, Field class GetWeatherArgs(BaseModel): city: str = Field(description="城市名称,如'北京'") date: str = Field(description="日期,格式 YYYY-MM-DD") @tool(args_schema=GetWeatherArgs) def get_weather(city: str, date: str) -> str: """获取天气预报""" return f"{city} {date} 天气多云"

2.3 构建并调用 Agent

使用create_agent函数将 LLM 和工具组装起来:

python

from langchain.agents import create_agent from langchain.chat_models import init_chat_model from langchain_tavily import TavilySearch llm = init_chat_model(model="gpt-4o-mini", model_provider="openai") search = TavilySearch(max_results=5) tools = [get_weather, search] # 自定义 + 第三方工具 agent = create_agent( model=llm, tools=tools, system_prompt="你是一个智能助手,请根据用户需求调用合适的工具。" ) # 一次性调用 result = agent.invoke({"messages": [{"role": "user", "content": "今天北京天气怎么样?"}]}) print(result["messages"][-1].content) # 流式调用(观察每一步) for step in agent.stream({"messages": [{"role": "user", "content": "今天北京天气怎么样?"}]}): print(step, end="\n\n")

流式调用会依次展示:LLM 推理 → 工具调用 → 工具返回 → 最终回复,非常适合调试。

2.4 LangSmith 调试

设置环境变量即可启用 LangSmith 追踪,可视化每一步的执行细节:

python

import os os.environ["LANGSMITH_TRACING"] = "true" os.environ["LANGSMITH_API_KEY"] = "你的 API Key" os.environ["LANGSMITH_PROJECT"] = "my-agent-project"

三、MCP 协议:标准化工具接入

3.1 为什么需要 MCP?

本地工具虽然灵活,但当你需要使用别人封装好的服务(如查火车票、操作数据库)时,每个服务的接入方式都不同(REST、WebSocket、gRPC...),如果每接入一个都要写适配代码,太繁琐。

MCP(模型上下文协议)是 AI 领域的“USB-C 标准”,它统一了 LLM 与外部工具之间的通信方式。

3.2 MCP 架构与工作流程

MCP 采用客户端-服务器架构,三个角色:

  • MCP Host:你的 LangChain Agent 程序

  • MCP Client:LangChain 的 MCP 适配器

  • MCP Server:提供工具能力的远程服务

工作流程

  1. 握手:Agent 启动时连接 Server,获取工具列表;

  2. 注入:工具描述和用户问题一起发给 LLM(LLM 不关心工具是本地的还是远程的);

  3. 决策:LLM 决定调用哪个工具、传什么参数;

  4. 路由执行:Host 通过 MCP 协议将调用请求发给 Server,Server 执行并返回;

  5. 继续推理:Host 将结果返回给 LLM。

对 LLM 来说,MCP 工具和本地工具没有区别——它看到的都是“工具名 + 描述 + 参数”。MCP 只改变了接入方式,对 LLM 完全透明。

3.3 编写 MCP Server(Stdio 方式)

本地开发调试最常用 Stdio 传输(通过标准输入输出通信)。

python

# mcp_server_stdio.py from mcp.server.fastmcp import FastMCP mcp = FastMCP("MyTools") @mcp.tool() def add(a: int, b: int) -> int: """计算两个整数的和""" return a + b @mcp.tool() def multiply(a: int, b: int) -> int: """计算两个整数的乘积""" return a * b if __name__ == "__main__": mcp.run(transport="stdio")

除了@mcp.tool(),MCP 还支持:

  • @mcp.resource:提供可读取的静态数据(如系统日志、配置文件),类似只读 API。

  • @mcp.prompt:提供预定义的提示词模板,让 Server 自带“使用说明书”。

3.4 编写 MCP Server(HTTP 方式)

当 Server 需要部署在远程供多个 Client 调用时,使用 Streamable HTTP:

python

# mcp_server_http.py from mcp.server.fastmcp import FastMCP mcp = FastMCP("MyTools") @mcp.tool() def add(a: int, b: int) -> int: return a + b if __name__ == "__main__": mcp.run(transport="streamable-http") # 默认 127.0.0.1:8000

对应的 Client 连接方式不同,但调用工具的 API 完全一致。

3.5 LangChain 接入 MCP

使用langchain-mcp-adapters库,可将 MCP Server 的工具直接转换成 Agent 可用的工具:

python

from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import create_agent from langchain_openai import ChatOpenAI client = MultiServerMCPClient({ "my-local-tools": { "transport": "stdio", "command": "python", "args": ["mcp_server_stdio.py"], } }) async def main(): tools = await client.get_tools() # 自动获取所有工具 llm = ChatOpenAI(model="gpt-4o-mini") agent = create_agent(llm, tools) result = await agent.ainvoke({"messages": [("user", "10加20等于多少?")]}) print(result["messages"][-1].content)

核心价值:通过MultiServerMCPClient可同时接入任意数量 MCP Server,对 Agent 来说,MCP 工具和本地@tool工具用起来没有任何区别。

3.6 本地工具 vs MCP 工具

对比维度本地工具(@tool)MCP 工具
定义位置写在项目代码中运行在独立的 Server 上
适合场景业务逻辑简单、不需要复用通用能力、跨项目/跨团队复用
维护方式和主项目一起维护独立部署、独立维护
生态复用无(只有自己能用)强(任何支持 MCP 的应用都能接入)

实际建议:项目早期或工具逻辑简单时,直接用@tool最快;当工具需要被多个项目复用,或想接入社区已有的服务时,用 MCP。两者可以混合使用。


小结(上篇)

  • Agent 是什么:LLM + 自主决策 + 工具调用,通过“感知→推理→行动”循环完成动态任务。

  • 工具定义:用@tool装饰器将普通函数转为 Agent 工具,写好 docstring 和类型注解是关键。

  • MCP 协议:统一了 LLM 与外部工具的通信方式,让 Agent 能像“插 USB”一样接入各种服务。

有了工具和 MCP,Agent 已经能调用外部能力了。但它还有一个明显的不足——每次调用都是“失忆”的,不记得之前说过什么。下一章我们将学习如何给 Agent 加上记忆,以及如何用中间件优化长对话和增加人工审核。敬请关注下篇