本文介绍了如何从零搭建一个完整的MCP Chat Agent系统,整合了MCP、LangGraph和Chainlit三大技术。系统架构包括Chainlit负责UI交互,LangGraph管理Agent执行流程,MCP处理工具协议,Ollama/OpenAI提供模型推理能力。教程详细展示了环境准备、MCP配置、核心Agent实现及Web UI集成,最终构建了一个支持多工具调用、流式输出、多轮对话与状态持久化的完整系统。
前言
随着大模型能力的提升,单纯的对话已经无法满足实际工程需求。越来越多的场景需要模型具备 调用外部工具、访问系统能力、执行复杂任务 的能力。
MCP(Model Context Protocol) 提供了一种统一、标准化的方式,让模型可以通过协议调用外部工具; LangGraph 则用于构建可控、可追踪的 Agent 推理流程; Chainlit 提供了一个轻量但功能完整的 Web Chat UI,非常适合 Agent 场景。
本文将介绍如何从零搭建一个:
- 支持 MCP 多工具调用
- 支持 Ollama / OpenAI 两种模型后端
- 支持流式输出
- 支持 Web UI(Chainlit)
- 支持多轮对话与状态持久化
的完整 MCP Chat Agent。
效果图

一、整体架构说明
系统整体架构如下:

Chainlit 负责 UI 与用户交互; LangGraph 负责 Agent 的执行流程与工具调度; MCP 负责工具协议与进程管理; Ollama / OpenAI 提供模型推理能力。
二、环境准备
1. 安装 Ollama 并拉取模型
ollama pull qwen2.5:7b
确认模型已加载:
ollama list
2. 安装 Python 依赖
pip install \ chainlit \ langchain-ollama \ langchain-openai \ langgraph \ langchain-mcp-adapters
三、MCP 配置说明(mcp.json)
示例 mcp.json:
{ "mcpServers": { "my_tools": { "command": "/usr/bin/python3", "args": [ "/home/user/langchain-mcp-demo/pymcp.py" ] } }}
说明:
- MCP Server 通过
stdio启动 - LangChain 会自动拉起、管理子进程
- 不需要手动启动 MCP Server
四、核心 Agent 实现(LangGraph + MCP)
1. Agent State 定义
from typing import Annotated, TypedDictfrom langgraph.graph.message import add_messagesclass State(TypedDict): messages: Annotated[list, add_messages]
该 State 用于在 LangGraph 中维护对话消息历史。
2. MCP Agent 实现
import asyncioimport jsonfrom langchain_ollama import ChatOllamafrom langchain_openai import ChatOpenAIfrom langchain_mcp_adapters.client import MultiServerMCPClientfrom langgraph.graph import StateGraph, STARTfrom langgraph.prebuilt import ToolNode, tools_conditionfrom langgraph.checkpoint.memory import MemorySaver
``````plaintext
class MCPAgent: def __init__(self, backend: str = "ollama"): if backend == "ollama": self.llm = ChatOllama( model="qwen2.5:7b", temperature=0.7, streaming=True, ) else: self.llm = ChatOpenAI( model="qwen3-30b-a3b-instruct-2507", temperature=0.7, api_key="sk-xxxxx", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", streaming=True, ) with open("mcp.json", "r", encoding="utf-8") as f: cfg = json.load(f) client = MultiServerMCPClient({ name: { "transport": "stdio", "command": s["command"], "args": s["args"] } for name, s in cfg["mcpServers"].items() }) self.tools = asyncio.run(client.get_tools()) self.llm = self.llm.bind_tools(self.tools) self.graph = self._build_graph() def _agent(self, state: State): return {"messages": [self.llm.invoke(state["messages"])]} def _build_graph(self): g = StateGraph(State) g.add_node("agent", self._agent) g.add_node("tools", ToolNode(self.tools)) g.add_edge(START, "agent") g.add_conditional_edges("agent", tools_condition) g.add_edge("tools", "agent") return g.compile(checkpointer=MemorySaver())
说明:
- MCP 工具通过
bind_tools注入模型 - LangGraph 使用
tools_condition自动判断是否调用工具 - MemorySaver 用于多轮对话状态保存
五、Chainlit Web UI 集成
1. 会话启动事件
import chainlit as cl@cl.on_chat_startasync def on_start(): cl.user_session.set("agent", MCPAgent("ollama")) cl.user_session.set("thread_id", "default") await cl.Message( content="MCP Chat Agent 已启动" ).send()
2. 消息处理(流式输出 + 工具提示)
@cl.on_messageasync def on_message(message: cl.Message): agent = cl.user_session.get("agent") thread_id = cl.user_session.get("thread_id") msg = cl.Message(content="") await msg.send() async for event in agent.graph.astream_events( {"messages": [("user", message.content)]}, config={"configurable": {"thread_id": thread_id}}, version="v2", ): etype = event["event"] if etype == "on_chat_model_stream": chunk = event["data"]["chunk"] if chunk.content: msg.content += chunk.content await msg.update() elif etype == "on_tool_start": await cl.Message( content=f"调用工具:{event['name']}", author="tool" ).send() elif etype == "on_tool_end": await cl.Message( content="工具执行完成", author="tool" ).send()
3. 完整代码
import chainlit as climport asyncioimport jsonimport osfrom typing import Annotated, TypedDictfrom langchain_ollama import ChatOllamafrom langchain_openai import ChatOpenAIfrom langchain_mcp_adapters.client import MultiServerMCPClientfrom langgraph.graph import StateGraph, STARTfrom langgraph.prebuilt import ToolNode, tools_conditionfrom langgraph.checkpoint.memory import MemorySaverfrom langgraph.graph.message import add_messages# ================== 配置 ==================OPENAI_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxx"OPENAI_API_BASE = "https://dashscope.aliyuncs.com/compatible-mode/v1"MCP_JSON_PATH = "/home/langchain-mcp-demo/mcp.json"class State(TypedDict): messages: Annotated[list, add_messages]class MCPAgent: def __init__(self, backend: str = "ollama"): # -------- 模型选择 -------- if backend == "ollama": self.llm = ChatOllama( model="qwen2.5:7b", temperature=0.7, streaming=True, ) else: self.llm = ChatOpenAI( model="qwen3-30b-a3b-instruct-2507", temperature=0.7, api_key=OPENAI_API_KEY, base_url=OPENAI_API_BASE, streaming=True, ) # -------- 加载 MCP -------- with open(MCP_JSON_PATH, "r", encoding="utf-8") as f: mcp_config = json.load(f) client_config = { name: { "transport": "stdio", "command": s["command"], "args": s["args"], } for name, s in mcp_config["mcpServers"].items() } client = MultiServerMCPClient(client_config) self.tools = asyncio.run(client.get_tools()) self.llm = self.llm.bind_tools(self.tools) self.graph = self._build_graph() def _agent(self, state: State): return {"messages": [self.llm.invoke(state["messages"])]} def _build_graph(self): g = StateGraph(State) g.add_node("agent", self._agent) g.add_node("tools", ToolNode(self.tools)) g.add_edge(START, "agent") g.add_conditional_edges("agent", tools_condition) g.add_edge("tools", "agent") return g.compile(checkpointer=MemorySaver())# ================== Chainlit 生命周期 ==================@cl.on_chat_startasync def on_start(): # 默认用 Ollama,你也可以加 UI 选择 cl.user_session.set("agent", MCPAgent(backend="ollama")) cl.user_session.set("thread_id", "default") await cl.Message( content="🤖 MCP Chat Agent 已启动(支持工具调用)" ).send()@cl.on_messageasync def on_message(message: cl.Message): agent: MCPAgent = cl.user_session.get("agent") thread_id = cl.user_session.get("thread_id") msg = cl.Message(content="") await msg.send() async for event in agent.graph.astream_events( {"messages": [("user", message.content)]}, config={"configurable": {"thread_id": thread_id}}, version="v2", ): etype = event["event"] if etype == "on_chat_model_stream": chunk = event["data"]["chunk"] if chunk.content: msg.content += chunk.content await msg.update() elif etype == "on_tool_start": await cl.Message( content=f"🛠️ 正在调用工具:**{event['name']}**", author="tool" ).send() elif etype == "on_tool_end": await cl.Message( content="✅ 工具执行完成", author="tool" ).send()
六、运行方式
chainlit run test.py

浏览器访问:
http://localhost:8000

支持功能:
- 流式模型输出
- MCP 工具自动调用
- 工具调用过程可视化
- 多轮对话上下文保持
如何系统的学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
一直在更新,更多的大模型学习和面试资料已经上传带到CSDN的官方了,有需要的朋友可以扫描下方二维码免费领取【保证100%免费】👇👇

01.大模型风口已至:月薪30K+的AI岗正在批量诞生

2025年大模型应用呈现爆发式增长,根据工信部最新数据:
国内大模型相关岗位缺口达47万
初级工程师平均薪资28K(数据来源:BOSS直聘报告)
70%企业存在"能用模型不会调优"的痛点
真实案例:某二本机械专业学员,通过4个月系统学习,成功拿到某AI医疗公司大模型优化岗offer,薪资直接翻3倍!
02.大模型 AI 学习和面试资料
1️⃣ 提示词工程:把ChatGPT从玩具变成生产工具
2️⃣ RAG系统:让大模型精准输出行业知识
3️⃣ 智能体开发:用AutoGPT打造24小时数字员工
📦熬了三个大夜整理的《AI进化工具包》送你:
✔️ 大厂内部LLM落地手册(含58个真实案例)
✔️ 提示词设计模板库(覆盖12大应用场景)
✔️ 私藏学习路径图(0基础到项目实战仅需90天)






第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】


3044

被折叠的 条评论
为什么被折叠?



