构建一个能说会做的智能体

这个作业属于哪个课程 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 之间频繁切换(如查天气、写备忘、建文档)。传统的聊天机器人只能“纸上谈兵”,无法真正落地执行操作。基于此,本小组设计并实现了“小办”智能体,核心需求如下:

  1. 自然语言理解与意图识别:用户能以日常对话的方式下达复合指令,例如“查一下杭州天气,写一份出行建议到 travel.md,再提醒我带充电器”。
  2. 外部工具调用(Action):Agent 需具备实际操作能力,不仅要说,还要能做。具体包括:
    • 调用外部 API:接入真实的和风天气接口,获取实时气象数据。
    • 结构化数据管理:将用户的待办任务持久化存储至本地 SQLite 数据库。
    • 文件系统操作:能够安全地读取、创建和追加本地 Markdown 文档。
  3. 多轮上下文记忆:在多轮对话中,Agent 需记住上下文。例如用户先要求“记一下明天带充电器”,紧接着说“再加一条带伞”,Agent 需要理解动作的连续性,而不是把它当成全新的孤立指令。
  4. 安全与边界控制:赋予 Agent 文件操作权限时,必须限制其只能在工作区(workspace/)内活动,防止误删或篡改系统文件。
  5. 可视化交互界面:提供友好的 Web 对话页面,降低使用门槛。

二、 业务流描述

image

整个智能体的业务流基于 MCP(Model Context Protocol) 架构实现。大模型作为“大脑”,通过 MCP 协议与作为“手脚”的各个 Server 进行通信。

核心流转路径如下:

  1. 用户输入:用户在 Gradio 界面中输入自然语言指令。
  2. Agent 接收与记忆加载:Agent 接收请求,并根据 thread_id 从 MemorySaver 中加载该会话的历史对话(确保多轮连贯)。
  3. 工具发现与思考:MultiServerMCPClient 将预先启动的 3 个 MCP Server(待办、天气、文件)暴露的 7 个工具列表提供给大模型。
  4. 意图解析与工具选择:大模型(DeepSeek Flash)分析指令,决定调用哪些工具以及传入什么参数。例如需要查天气时,生成 get_weather(city="杭州") 的调用请求。
  5. MCP Server 执行操作:
    • Weather Server:收到请求后,通过 httpx 请求和风天气 API,将结果返回给大模型。
    • File Server:收到写文件请求后,先经过 _safe() 路径白名单校验,通过后写入 workspace/travel.md。
    • Todo Server:收到添加待办请求后,操作 todos.db 执行 SQL 插入。
  6. 结果整合与输出:大模型汇总多个工具的执行结果,生成一段通顺的自然语言回复,展示在 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 初始化循环冲突。

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 或更高版本。建议在虚拟环境中运行以隔离依赖。

第一步:克隆项目并安装依赖

  1. 克隆代码到本地并进入目录
    git clone https://github.com/你的组名/仓库名.git
    cd 仓库名

  2. 创建并激活虚拟环境(以 Windows PowerShell 为例)
    python -m venv .venv
    ..venv\Scripts\Activate.ps1

  3. 一键安装所有依赖
    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 应用有了更深的底气。

posted @ 2026-10-23 21:33  JJ123456789  阅读(4)  评论(0)    收藏  举报