软件工程课程第二次团队作业
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/202501SoftwareEngineering/ |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/202501SoftwareEngineering/homework/13559 |
| 这个作业的目标 | 构建一个能说会做的智能体,能与外部API或数据库交互,并提供一个简洁的前端界面(网页或桌面端) |
| 学号 | 102301112、102301126、102301543、102301428、102301540、102301135、102301517、102301143、102301118、102301243、102301111、102301129 |
需求描述
灵感来源
我们的初衷是利用MCP框架搭建一个有利于学生进行学习的平台。目前的主流AI软件,在文科方面,已经能够实现强大的文字编辑能力,但在数理化等理工科学习方面仍有欠缺,比如在概率论与数理统计、算法与数据结构等科目中,复杂的概念往往难以被文字直观展示,基于此需求出发,我们希望能借助现有的智能体思想,建构一个可以辅助学生直观理解课程知识点、未来进化为一个全能型的学业智能体,针对现有大学生活软件如“福uu”的各项痛点,实现主动化、个性化、直观化这三个方向的进化。
当前实现
因此,在这次小作业中,我们希望能够利用MCP框架,让AI实现html绘图功能,能够在聊天界面中实时绘图、实时展示,以此来更好的辅助学生学习数理和代码知识。在开发前,我们小组经过多次会议讨论,针对前后端的基础架构进行了慎重选择,最终采用了go+vue的实现方式,便于未来高并发、多端共用的拓展。在开发中,我们决定通过调用Plotly.j、ECharts.js等常见可视化库,我们将为用户提供真实可信的图形化服务,帮助学生学习。功能拓展方面,我们预留了编程相关的tools,通过仿照目前cursor/copilot的agent模式,使用MCP来实现AI感知本机目录树、运行代码并查看stdout,给出更实际的解决方案,期望在未来的大作业开发中得到实现
TODO List
-
本地代码编译和智能检错
-
更加完善、功能全面且与本地APP开发对接的前端
-
合理的日程安排和主动的智能提醒
业务流描述
-
sse connection:前后端通过SSE实现流式传输,对话上下文暂时保存在后端本地内存中 -
MCP host:host作为HTTP server,同时作为AIProviderCli与MCPCli,将AI的SSE event推送到前端,同时执行AI需要的toolcall -
MCP server集群:host与server初次连接时,server会返回拥有的工具,之后server会执行host发来的toolcalls,返回toolResults -
consul:服务注册与服务发现中心,通过工厂模式实现对集群与单点通信的兼容,host通过toolCli可以实现对多个mcp_server的调用与tool的聚合,还有热更新新的tool,实现对server与server不同功能间的解耦,server与host连接间的解耦,为未来大项目工程化落地做好准备
实现说明
前端
前端基于Vue+Vite实现,并通过axios+sse与后端进行对接,现已支持流式输出、可视化iframe插入、本地可视化库缓存、网页导出等功能,并暂时采用localStorage储存对话,后期预留账号系统接入
特性一览
-
黑白简约 UI:统一灰度调色板、干净留白、对比度友好。
-
完整响应式:
-
桌面端固定侧边栏 + 主区域
-
移动端抽屉式侧边栏(遮罩点击关闭)
-
-
安全 Markdown 渲染:
-
基于
marked + dompurify的渲染与净化 -
<draw>占位生成图片(可对接你的图像 API) -
<htmath>在 sandboxed iframe 中安全渲染可视化/HTML 片段 -
MathJax 公式(自动注入,行内/块)
-
-
会话与消息:
-
新建/切换/删除会话、标题自动生成
-
SSE 流式响应(示例:
/api/v1/chat/sse) -
本地持久化
localStorage -
消息操作:复制、重新生成、导出为单页 HTML
-
-
可视化库管理:
-
统一配置与注入第三方库(如 Plotly/ECharts/D3/Chart.js/Leaflet)
-
支持启用/禁用、离线缓存到 Cache Storage、状态查看
-
流式渲染阶段展示“正在加载可视化…”占位,闭合后即时注入
-
-
主题系统:
-
跟随系统明暗模式(
prefers-color-scheme) -
手动切换(顶部按钮):
light / dark / 跟随系统
-
-
可访问性与体验:显性焦点样式、键盘可用、自定义滚动条、尊重 reduce motion
主题系统
主题变量定义在 src/styles/theme.css。
-
核心颜色变量:
-
背景:
--bg、--bg-elev-1/2/3 -
文本:
--fg、--fg-muted、--fg-dim -
边框:
--border、--border-strong -
强调:
--accent、--accent-weak
-
-
尺寸变量:
-
圆角:
--radius-sm/md/lg -
间距:
--space-1 ~ --space-7 -
容器宽度:
--container-max
-
-
字体:
--font-sans、--font-mono -
焦点环:
--focus-ring
跟随系统 & 手动覆盖
-
默认跟随系统的明暗偏好(
prefers-color-scheme)。 -
手动覆盖:在
html上使用data-theme属性即可:-
data-theme="light"/data-theme="dark"强制浅/深色 -
移除该属性则恢复跟随系统
-
-
运行时切换:
ChatView.vue中的“月亮”按钮会在三种状态间切换:light → dark → 跟随系统 → ...,并持久化在localStorage(键:theme)。
使用主题变量(示例)
.example-card {
background: var(--bg-elev-1);
color: var(--fg);
border: 1px solid var(--border);
border-radius: var(--radius-md);
}
响应式与交互
-
宽度 ≤ 1024px 时:
-
侧边栏变为抽屉:点击顶部“菜单”按钮弹出;点击遮罩关闭。
-
样式过渡使用
transform,性能友好。
-
-
滚动容器建议加类
u-scrollbar以使用主题滚动条样式。
可视化库与 <htmath>
-
在 Markdown 中使用
<htmath>...</htmath>包裹 HTML 片段,可在 sandboxed iframe 内安全渲染。 -
组件会移除片段内的外链脚本引用,并改为统一从配置注入:
-
配置位置:
src/config/visualization-libs.config.js -
UI 管理:设置面板中的“可视化库配置”(启用/禁用、下载缓存、清理缓存)
-
-
已内置库:Plotly(默认启用)、ECharts、D3、Chart.js、Leaflet(默认禁用,可按需启用)
-
缓存:库可下载到 Cache Storage 离线使用;状态在设置面板中可见。
-
流式体验:
-
流式阶段若出现
<htmath>开始标签,将先展示“正在加载可视化…”占位; -
一旦收到闭合标签,立即注入 iframe 并自适应高度;流式结束后做一次完整渲染(含 MathJax/图片等补齐)。
-
示例(Plotly):
这里是一段图表:
<htmath><div id="plot" style="width:100%;height:360px"></div><script>
const el = document.getElementById('plot');
Plotly.newPlot(el, [{ y: [1,3,2,4] }], { margin: { t: 20 } });
</script></htmath>
安全与隔离:iframe 使用受限的 sandbox 属性。你可在 visualization-libs.config.js 中调整:
-
sandboxConfig.attributes:允许的能力白名单 -
sandboxConfig.strict:为true时禁用allow-same-origin以增强隔离 -
cacheConfig.maxSize/debug:控制 iframe 缓存策略与日志
运行示例:
后端
鸡架
后端基于go语言来实现,得益于go语言的高并发特性与内存友好,很适合作为web项目后端与AI Agent
-
项目整体架构采用微服务架构,各个服务预计基于整洁架构进行实现,通过脚本文件统一部署
-
HTTP框架选用了字节跳动的hertz框架,提供了基于thrift的项目脚手架生成,便于快速开发,同时支持生成
openapi.yaml,便于前后端接口对齐对接 -
mcp框架选用了mcp-go,目前社区活跃,已支持最新的
StreamableHTTP协议 -
服务注册通过consul来实现,自行二次封装实现基于
TCP/IP进行StreamableHTTP连接
-
logger基于高性能的zap进行二次封装,并且支持log统一输出
-
config通过viper来读取yaml文件统一管理
-
AI模型支持本地与远程两种连接方式,后续可自行微调模型进行连接
业务
- devCodeRunTool
这个tool包括了cat、tree、cmd三个function,分别对应查看文件、查看目录树、运行命令,通过在本地部署的mcp_server运行函数,使得AI能够对本地的代码产生感知
- AIScienceAndEngineeringBuildHtml
通过再开一个AI会话加入prompt,使得AI能够自动生成html并由mcp_server返回作为tool_result,根据openai规范,前端可以对html做展示
使用示例
后端
环境要求
-
Go 1.25
-
docker与docker-compose(orbstack)
-
从example.yaml copy后,确保ai_provider的api_key存在
本地启动
make env
make host
make mcp_local#在另一个终端运行
make mcp_remote#在另一个终端运行
docker启动(network=host模式)
make env
make docker-run-host
make docker-run-mcp_local
make docker-run-mcp_remote
无go环境启动
make env
make pull-run-host
make pull-run-mcp_local
make pull-run-mcp_remote
前端
环境要求
- Node.js 18+(推荐)
安装依赖
npm install
开发模式
npm run dev
构建
npm run build
Github链接
团队仓库:https://github.com/FantasyRL/HachimiONanbayLyudou/tree/main/homework2
为提高维护效率,我们将前后端仓库分开维护,直接访问链接如下:
后端:https://github.com/FantasyRL/go-mcp-demo
前端:https://github.com/RealSeverj/learning-mcp
小组分工
| 姓名 | 方向 | 工作内容 |
| 肖垲 | 后端 | 搭建项目基建、编写docker部署脚本、编写后端文档 |
| 许竣阳 | 后端 | 统一client与tool初始化入口 |
| 曾义山 | 后端 | 实现sse流式对话与openAI-API兼容 |
| 彭志成 | 后端 | 实现sse流式对话与openAI-API兼容 |
| 陈昌昊 | 后端 | 实现codeRunTool |
| 陈文嘉 | 后端 | 实现aiSEsolverTool |
| 苏郑熙凡 | 前端 | 搭建基础框架、编写前端文档,实现API对接 |
| 周韩煜 | 前端 | 编写可视化相关组件 |
| 鲍晓鹏 | 前端 | 编写代码运行相关组件 |
| 郑隆熙 | 前端 | 优化界面动画、编写博客和演示文档相关 |
| 刘佳 | 前端 | 对渲染流程进行调优 |
| 李文伟 | 前端 | 优化SSE流显示 |
每个小组成员的心得
102301111 周韩煜
经过这段时间的学习,我对前端知识有了初步的了解。最初,我通过西二前端课程学习了HTML和CSS的基础语法,之后尝试自己创建了一个Vite + Vue项目。在前端负责人和组长的悉心指导下,我逐渐掌握了编写可视化相关组件的方法。在完成作业的过程中,我们小组进行了多次交流与讨论。通过团队沟通,我对项目的目标和产品定位有了更深入的理解。这次实践让我不仅积累了扎实的理论知识,也获得了宝贵的实战经验。
102301112 郑隆熙
作为本次软件工程小组的组长,我承担了Scrum和部分Product Owner的职责。我积极安排每次的小组讨论会,在10月15、16和19日,我各组织了一次会议,讨论了作业的方向、创新点和学习进度等内容。由于不同同学的学习进度和能力各不相同,利用会议,我既掌握了初学的同学的学习情况,又能够依靠有一定项目经历的同学,实现项目的推进。
本次作业我作为一个前端的新手,从零开始学习了前端相关的知识,对前端有了一些了解。我在先前有一定的HTML和CSS知识,又通过菜鸟教程学习了如何Vue框架的相关内容,之后我尝试自己创建了一个Vue + Vite的项目,实现了一个简单的个人主页。此外,我在学习并尝试如何调用高德地图的API,也正在学习如何优化界面动画的相关知识,未来也将继续在这个方向为团队做出贡献。
经过本次的学习,我也对后端有了一些理解,也更加清晰了解到如何使用github进行团队合作,如何更好的运营和管理团队。
总的来说,我对本次能够和许多同学一起参与合作的经历深感荣幸,无论是组织能力还是工程能力,我也从中受益匪浅。我为能为我们智能体项目做出贡献而感到自豪。
102301118 许竣阳
通过系统学习Go语言基础语法与go module依赖管理,我体会到了官方工具链的简洁高效,在开发的过程中,我深刻认识到了及时沟通和团队协作的重要性,并学会了MCP等的基本原理。通过实践,我对理论知识的掌握更好了,并且认识到了“计算机是一门实践的学科”。
102301126 苏郑熙凡
由于具有一定的前端开发经验,在这次任务中,我承担起了前端部分的主要责任,初次接触SSE和AI相关对接、以及前台组件、iframe缓存,我对前端与localstorage有了更深入的理解。与后端的合作和与团队成员的沟通也让我受益匪浅。
102301129 彭志成
经过这段时间的学习我收获了很多。之前对Go语言只是听说过,这次真正用起来才发现它的魅力。Go的语法很简洁,没有那么多复杂的特性,但用起来效率很高。尤其是并发编程那块,用goroutine和channel处理多任务特别顺手,代码写起来也清晰易懂。不过在最初搭环境的时候,我找了网上很多教程,试了很多才在vscode上配置好了go,不然用goland还要收费。。。
同时我也对后端有了跟多的理解,也更加清晰了解到如何使用github进行团队合作,同时小组内也有很多学习资料,大家交流氛围也十分融洽,希望在后续能够继续更新完善我们的项目。
102301135 李文伟
这段时间的前端学习,让我完成了从 “静态样式实现” 到 “交互功能开发” 的初步跨越:不仅掌握了 JavaScript 基础知识,能独立用代码实现元素控制、事件响应等基础交互,不再局限于 CSS 静态页面;还入门 Vue 框架,提升开发效率的同时对前端工程化有了认知;理清了完整开发流程,明白 “语法 + 框架 + 工具” 配合的关键。与此同时,我们小组多次的组会以及小组成员的指导让我在学习上更有方向,明确目标少走了很多弯路。后续我会继续巩固基础、深入学习框架知识,通过实际项目不断提升前端开发水平。
102301143 曾义山
作为一个Go语言的初学者,我负责了后端分工,这是一次从零开始的挑战与探索。我的核心任务是实现SSE流式对话并与OpenAI-API兼容。起初,我对Go的语言和应用知之甚少。我先学习了西二工作室go语言的项目,并通过项目实践,深入理解了SSE技术如何实现服务器向客户端的持续数据推送。同时,我在队友的帮助和指导下设计了后端的请求与响应格式,使其与OpenAI API兼容。整个过程让我深刻体会到,将理论知识转化为可运行、可交互的代码所带来的成就感。看到前端成功接收到后端推送的流式消息,我感到无比兴奋。这次经历不仅让我入门了Go语言和后端开发,更锻炼了我解决实际问题的能力。我为能为我们智能体项目做出贡献感到自豪。
102301243 陈文嘉
作为后端,我快速学习了西二的Go教程,学会github的基本用法,go环境的配置与基本语法,并在队友的指导和帮助下负责aiSEsolverTool部分。
这是MCP框架下用Go开发的AI辅助科学工程求解工具,集成OpenAI接口,能处理数学或工程问题并生成带
此过程深化了我对MCP框架、Go集成AI及模型行为控制的理解,认识到工程化中平衡简洁与扩展性的重要性,并且体会到多人协作与单人作业的不同。例如,前端与后端的通信,互不干扰地进行多人开发,有效的会议讨论等等。
计划进一步学习Go和MCP,为项目进一步添砖加瓦。
102301428 刘佳
“欲穷千里目,更上一层楼。 ”
——王之涣《登鹳雀楼》
初入软件工程小组,我不过一介前端新兵,面对满堂英才,心中既敬且惧。组长郑隆熙运筹帷幄,统筹如棋手布势;苏郑熙凡执掌前端,代码行云流水;肖垲坐镇后端,逻辑缜密如青铜镜映秋水。诸君皆神兵天降,而我,不过一叶扁舟,初临这片数字的海。
然“仰天大笑出门去,我辈岂是蓬蒿人。 ”
我虽自觉浅陋,却亦心怀热火。于诸贤之间,不求耀眼,但求同行;不敢自诩翘楚,但愿为星火添薪。
在一次次组会之中,我们如夜航者聚灯,互通彼此的光。每周一次的汇报,不仅是进度的盘点,更是思想的碰撞。我在他们的指点中明白,编程不只是语法的堆砌,而是思想与逻辑的共舞,是一场关于秩序与创造的盛宴。
此次大作业,我肩负前端之责。幸得昔日在西二自习室所积的 HTML 与 CSS 之基,又得苏郑熙凡同学倾囊相授,方敢尝试以 Vue 框架构筑页面。初识其语法,如登山者初见雪岭,眼中既惊且惑;然渐入其境,方悟组件之妙、路由之灵,感叹“ 大道至简,繁在枝末 ”。当浏览器中那一行行代码化作灵动的界面,我忽觉所有的努力都不曾辜负。
组会间,郑隆熙的战略眼光如北辰指路,肖垲的逻辑思维如工笔细描,苏郑熙凡的设计思路似春风拂面——我在他们的言语与行动中,看见了“团队”的真正含义:并非强者独行,而是群星共耀。
古人云:“ 青,取之于蓝而胜于蓝;冰,水为之而寒于水。 ”
我愿以此自勉——虽为后进,然志不甘后。未来的时光里,我将继续精进前端技艺,向诸位大佬看齐,于千行代码间探求秩序,于微光之间铸就璀璨。
若有一日,我们的项目能在浩瀚网络之中璨然生辉,
那必是我们共同的信念与汗水,
在时光的编译器中,
化为了永不停止的运行。
102301517 肖垲
大体理解了mcp的使用场景与传输时的新协议,并根据其尽可能在鸡架上做了工程化的适配,特别是consul的二次封装
102301540 陈昌昊
在本次小组作业中,我作为后端开发的一员,主要负责实现codeRunTool这一功能模块。在整个开发过程中,我不仅学到了很多技术层面的知识,还对团队协作有了更深的理解。
技术收获
-
深入理解Go语言特性:后端基于Go语言开发,让我对Go的高并发特性和内存管理有了更深的认识。尤其是在处理流式数据和工具调用时,Go的协程和通道机制表现出了巨大的优势,这让我对Go语言的应用场景有了更全面的了解。
-
掌握工具链与框架:在项目中,我学习了如何使用Hertz框架处理HTTP请求,以及如何利用MCP-go框架实现工具调用和流式协议。同时,通过使用Zap进行日志管理,我对高性能日志处理有了更直观的感受。
-
探索AI与后端的结合:项目中支持本地和远程AI模型的连接方式,让我对AI开发的实际应用场景有了更多思考。并且,我学习了如何通过API与AI模型进行交互。
团队协作体验
-
高效分工与合作:通过明确的分工,我们团队能够快速进入各自的工作领域并高效完成任务。我负责的
codeRunTool模块与团队其他模块紧密结合,最终实现了完整的功能。 -
代码规范与统一管理:团队中统一使用Viper管理配置、Zap进行日志记录,让我深刻体会到代码规范的重要性。统一的开发模式不仅减少了沟通成本,还提高了代码的可维护性。
-
前后端协同开发:与前端团队的协作让我认识到,一个完整的项目不仅需要功能的实现,还需要良好的用户体验。我们通过SSE连接和API对齐,实现了前后端无缝对接。
个人成长与反思
-
独立解决问题的能力提升:在实现
codeRunTool的过程中,我遇到了不少技术难题,比如如何优化工具的执行效率、如何处理异步请求等。通过查阅文档、分析问题并不断调试,我逐渐掌握了独立解决问题的能力。 -
对系统设计的深入思考:这次项目让我认识到,一个优秀的系统设计不仅需要实现功能,还需要考虑扩展性、性能和用户体验。在后续的开发工作中,我要更加注重这些方面的平衡。
-
时间管理与优先级设定:在任务较多的情况下,我学会了如何合理安排时间并优先完成关键任务。这对我的时间管理能力提出了更高的要求,也让我更加注重效率。
总结
这次小组作业对我来说是一次非常宝贵的学习经历。我不仅提升了自己的技术能力,还学会了如何在一个团队中高效协作并完成复杂项目的开发。在未来的学习和工作中,我希望能够继续保持这种学习的热情和团队合作的精神,不断提升自己,迎接更大的挑战。
102301543 鲍晓鹏
初次了解MCP的概念、实现原理,初步了解了MCP的基本知识,通过前端页面也更清晰了解MCP的使用机制。

浙公网安备 33010602011771号