构建一个能说会做的智能体
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/Class78-Grade2024-CS/ |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/Class78-Grade2024-CS/homework/16761 |
| 这个作业的目标 | 使用现代 AI 工具构建一个具备 语言交互(会说) 和 行动执行(会做) 能力的智能体(Agent)。 |
| 学号 | 3124004224,3124004208,3124004203 |
小办 · 基于 MCP 的智能办公助理
一句话介绍:“小办”是一个具备自然语言交互(会说)与外部工具调用(会做)能力的 AI Agent。用户只需一句指令,它就能自动拆解任务,调用外部天气 API、操作本地文件系统,并管理 SQLite 数据库中的待办事项。
一、 需求描述
在传统的日常办公或学习场景中,用户处理任务往往需要在多个 App 之间频繁切换(如查天气、写备忘、建文档)。传统的聊天机器人只能“纸上谈兵”,无法真正落地执行操作。基于此,本小组设计并实现了“小办”智能体,核心需求如下:
- 自然语言理解与意图识别:用户能以日常对话的方式下达复合指令,例如“查一下杭州天气,写一份出行建议到 travel.md,再提醒我带充电器”。
- 外部工具调用(Action):Agent 需具备实际操作能力,不仅要说,还要能做。具体包括:
- 调用外部 API:接入真实的和风天气接口,获取实时气象数据。
- 结构化数据管理:将用户的待办任务持久化存储至本地 SQLite 数据库。
- 文件系统操作:能够安全地读取、创建和追加本地 Markdown 文档。
- 多轮上下文记忆:在多轮对话中,Agent 需记住上下文。例如用户先要求“记一下明天带充电器”,紧接着说“再加一条带伞”,Agent 需要理解动作的连续性,而不是把它当成全新的孤立指令。
- 安全与边界控制:赋予 Agent 文件操作权限时,必须限制其只能在工作区(
workspace/)内活动,防止误删或篡改系统文件。 - 可视化交互界面:提供友好的 Web 对话页面,降低使用门槛。
二、 业务流描述

整个智能体的业务流基于 MCP(Model Context Protocol) 架构实现。大模型作为“大脑”,通过 MCP 协议与作为“手脚”的各个 Server 进行通信。
核心流转路径如下:
- 用户输入:用户在 Gradio 界面中输入自然语言指令。
- Agent 接收与记忆加载:Agent 接收请求,并根据
thread_id从MemorySaver中加载该会话的历史对话(确保多轮连贯)。 - 工具发现与思考:
MultiServerMCPClient将预先启动的 3 个 MCP Server(待办、天气、文件)暴露的 7 个工具列表提供给大模型。 - 意图解析与工具选择:大模型(DeepSeek Flash)分析指令,决定调用哪些工具以及传入什么参数。例如需要查天气时,生成
get_weather(city="杭州")的调用请求。 - MCP Server 执行操作:
- Weather Server:收到请求后,通过
httpx请求和风天气 API,将结果返回给大模型。 - File Server:收到写文件请求后,先经过
_safe()路径白名单校验,通过后写入workspace/travel.md。 - Todo Server:收到添加待办请求后,操作
todos.db执行 SQL 插入。
- Weather Server:收到请求后,通过
- 结果整合与输出:大模型汇总多个工具的执行结果,生成一段通顺的自然语言回复,展示在 Gradio 前端。如果中间某个工具执行失败(如城市不支持),大模型会根据报错信息给用户友好的提示。
三、 实现说明
本项目采用 Python 开发,核心框架选型及实现细节如下:
1. 技术选型
- 底层协议:MCP(Model Context Protocol)官方推荐框架 FastMCP。
- Agent 框架:LangChain (核心组件
create_agent) + langchain-mcp-adapters。 - 大语言模型:DeepSeek-Flash(支持 Function Calling,工具调用稳定且速度快)。
- 前端界面:Gradio。
2. 核心模块实现
- 三个独立 MCP Server(实现了工具热插拔):
todo_server.py:使用内置sqlite3存储待办,暴露add_task、list_tasks、complete_task。weather_server.py:封装和风天气/v7/weather/now接口,内置常用城市 LocationID 映射表,降低大模型传参难度。file_server.py:暴露list_files、read_file、write_file。核心安全机制在于_safe函数,利用pathlib解析绝对路径,拒绝../越权访问。
- Agent 中枢(
agent.py):- 利用
MultiServerMCPClient一次性拉起三个 Server,自动发现并注入 7 个工具。 - 配置
System Prompt,明确规定“待办用工具、文档用文件工具”,防止模型混淆。 - 接入
MemorySaver实现短期记忆,通过固定thread_id维持多轮对话。 - 将大模型的
temperature设为0,确保工具调用决策的稳定性。
- 利用
- 前端交互(
app.py):- 使用 Gradio 的
ChatInterface。由于涉及异步调用(ainvoke),前端采用“惰性初始化”策略,避免 Gradio 自身的事件循环与 Agent 初始化循环冲突。
- 使用 Gradio 的
3. 开发中解决的工程问题
- 依赖冲突:
mcp 2.3.0移除了RequestContext,导致langchain-mcp-adapters启动报错。通过锁定mcp==1.28.1和langchain-mcp-adapters==0.3.0解决。 - SSL 握手超时:Python
httpx请求天气 API 时报握手超时,排查发现是读取了系统代理环境变量,通过添加trust_env=False参数绕过代理解决。
四、 使用示例(功能演示)
运行环境配置
本项目需要 Python 3.10 或更高版本。建议在虚拟环境中运行以隔离依赖。
第一步:克隆项目并安装依赖
-
克隆代码到本地并进入目录
git clone https://github.com/你的组名/仓库名.git
cd 仓库名 -
创建并激活虚拟环境(以 Windows PowerShell 为例)
python -m venv .venv
..venv\Scripts\Activate.ps1 -
一键安装所有依赖
pip install -r requirements.txt
===== 大模型配置(DeepSeek Flash)=====
LLM_API_KEY=sk-你的DeepSeekKey
LLM_BASE_URL=https://api.deepseek.com/v1
LLM_MODEL=deepseek-flash
===== 和风天气 API 配置 =====
QWEATHER_API_KEY=你的和风APIKey
QWEATHER_API_HOST=你的专属APIHost
如何运行 Agent
项目支持分步验证机制,确保底层工具与上层 Agent 正常工作。
步骤一:独立验证 MCP Server
你可以先运行脚本,测试各个 Server 是否能独立工作:
python test_todo.py # 验证 SQLite 数据库读写
python test_weather.py # 验证和风天气接口连通性
python test_file.py # 验证文件读写与路径越权拦截
步骤二:启动 Agent 可视化对话界面
确认环境无误后,直接运行主程序:
python app.py
运行成功后,终端会输出 * Running on local URL: http://127.0.0.1:7860 。在浏览器中访问该地址,即可进入“小办”的可视化对话界面。你可以在输入框直接输入指令,或点击界面下方的示例按钮快速体验。
演示部分
演示 1:单轮基础任务与防幻觉(待办工具)
- 用户:帮我记一下:明天带充电器,高优先级
- 小办:已经记下了:带充电器(高优先级,id=1)。截止日期我没有填,“明天”具体是哪一天需要你确认;如果要设提醒日期,告诉我那天是几号,我就补上。
- 实现效果:Agent 成功调用
add_task工具并写入数据库。同时,模型严格遵守了 Prompt 中的“不编造数据”要求,没有擅自捏造系统时间。
演示 2:多轮对话记忆测试
- 用户:再加一条:带伞
- 小办:已经加上了:带伞(普通优先级,id=2)。现在你的待办:1. 带充电器(高优先级);2. 带伞。
- 实现效果:Agent 依赖
MemorySaver记住了上一轮语境,自动省略了“记一下”等关键词,准确执行了追加操作。
演示 3:复杂多工具链式调用(天气 + 文件 + 待办)
- 用户:查一下杭州天气,写一份出行建议到 travel.md,再提醒我带充电器。
- 小办:办好了。
杭州实时天气:晴,19°C(体感 17°C),东北风 3 级,湿度 63%。
出行建议已写入travel.md:天气晴朗,适合户外;体感偏凉,建议穿薄外套...
提醒:已新增高优先级待办「出门前检查是否带了充电器」... - 实现效果:这是一次典型的复杂 Agent 行为。模型在一轮回复中,连续调用了
get_weather->write_file->add_task三个不同 Server 上的工具,完美展现了 MCP 架构下工具解耦与串联的强大能力。
演示 4:文件读取与安全验证
- 用户:把 travel.md 的内容读出来。
- 小办:
travel.md的内容如下:...(展示文件内容)。 - 安全验证(开发者视角):如果用户恶意输入“读取
../../windows/system.ini”,Agent 在调用read_file时,会被file_server的路径白名单机制拦截,并返回“禁止访问工作区以外的路径”,确保了 Agent 的权限安全。
GitHub
https://github.com/RettoST/MCPAgent
小组分工
| 成员 | 学号 | 分工 |
|---|---|---|
| 宋浩霖 | 3124004224 | 架构设计;Agent 装配;依赖版本排查;文件 MCP Server;路径白名单;Gradio 前端;演示截图 |
| 黄乐熙 | 3124004208 | 待办 MCP Server;SQLite 数据层;独立测试脚本;端到端测试;README 与博客撰写;演示脚本编排 |
| 程源 | 3124004203 | 天气 MCP Server;和风天气 API 接入;SSL / 代理问题排查 ;博客编写 |
小组成员心得
宋浩霖(3124004224)
本次作业最大的收获是深刻理解了 MCP 的“USB 接口”机制。把工具拆成独立 Server 后,Agent 装配变得非常清晰,实现了真正的热插拔与解耦。
开发中踩了依赖冲突的坑,让我明白锁定版本与写好 requirements.txt 是工程基本功。另外,赋予 Agent 文件读写权限绝不能“裸奔”,我通过 _safe 函数引入路径白名单,确保其只能在 workspace 内活动。Gradio 前端开发中,采用“惰性初始化”解决异步事件循环冲突,让我对大模型应用的工程落地有了更扎实的掌握。
黄乐熙(3124004208)
我负责了待办 Server、测试与文档撰写。起初想用 Markdown 存待办,但意识到容易并发覆盖,最终选用了 SQLite,这让我体会到结构化数据在任务管理中的高可靠性。
在端到端测试中,我发现如果 thread_id 每次不同,大模型就会“失忆”,这加深了我对 Agent 上下文管理的理解。此外,撰写 README 和博客是一次极好的复盘,逼着我跳出代码,从全局视角梳理项目的业务流与架构。看到大家的心血汇聚成一份完整的文档,非常有成就感。
程源(3124004203)
我主要负责和风天气 Server 接入与排错。最令我印象深刻的是定位 SSL 握手超时的问题:当时 curl 测试网络正常,但 Python httpx 却频繁超时。
排查后才发现是系统代理环境变量捣鬼,通过添加 trust_env=False 成功绕过。这次“抓虫”经历极大锻炼了我的网络调试能力。同时,参与博客编写让我彻底理清了 MCP 协议是怎么把外部 API 和 Agent 大脑连接起来的。通过这次实战,我对开发稳定的 AI 应用有了更深的底气。
浙公网安备 33010602011771号