软件工程第四次作业:基于Java的MCP待办清单智能体实现

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class56-Grade2024-CS
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class56-Grade2024-CS/homework/16760
这个作业的目标 实现一个基于MCP思想的待办智能体;使用Java开发,大模型负责自然语言意图识别,输出标准化工具指令,程序解析指令完成待办增删查操作,理解智能体+工具调用的工作模式
学号 依木拉木·阿不都苏力(3124004111)、李晨昀(3224004155)、刘心怡(3224004156)、吴纯瑶(3224004157)、杨添媛(3224004158)、艾力夏提·艾海买提(3124004121)、杨宗林(3124004146)

基于Java+大模型的MCP待办智能体设计与实现

一、需求描述

本项目是MCP智能体团队作业,开发一个待办事项助手智能体。
用户使用自然语言进行交互,不需要输入固定命令。智能体需要识别用户意图,调用对应的工具完成待办操作:

  1. 添加待办:用户描述任务,智能体新增一条待办事项
  2. 查询待办:查看当前全部待办列表
  3. 删除待办:根据序号删除指定待办事项

约束:

  • 使用纯Java开发,不引入Maven;
  • 遵循MCP思想:大模型只负责理解语言、输出规范工具指令,工具执行逻辑由Java代码完成;
  • 控制台交互,稳定完成三类基础工具调用。

加分尝试:本次基础版本支持多轮对话,用户可以连续下发多条指令。

二、业务流描述

完整业务流程:

  1. 用户在控制台输入自然语言(例如:帮我加一个晚上复习软件工程的任务)
  2. Java程序将用户输入文本发送给GLM大模型,并通过提示词约束模型输出固定格式指令
  3. 大模型识别用户意图,返回标准化指令:ADD|xxx / LIST / DEL|序号
  4. Java程序拿到指令字符串,解析指令类型,执行对应的工具逻辑
  5. 程序执行完成,将执行结果反馈打印到控制台,等待用户下一条输入
  6. 循环交互,直到用户输入exit退出程序

流程图文字概括:
用户自然语言输入 → HTTP请求LLM → LLM输出工具指令 → Java指令解析分发 → 操作待办列表 → 返回执行结果

三、实现说明

开发环境

  • JDK:JDK17
  • IDE:IDEA
  • 开发方式:纯Java单文件项目,无Maven
  • 大模型:智谱GLM-4-Flash
  • 存储:内存ArrayList临时保存待办(重启丢失)

模块划分

  1. 主交互模块 main():控制台循环读取用户输入,串联整个调用流程
  2. LLM调用模块 callLLM():构造HTTP请求,发送prompt给大模型,解析返回JSON,提取工具指令
  3. 指令分发模块 handleToolCommand():判断指令前缀,分别执行新增、查询、删除待办逻辑
  4. 提示词约束:强制模型只能输出固定指令,禁止多余解释文字,保证程序可以稳定解析

核心源代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * 软件工程团队作业:MCP待办智能体
 * 功能:自然语言交互,支持添加待办、查看待办、删除待办
 * MCP思想:大模型负责意图识别输出工具指令,Java程序负责工具执行
 */
public class TodoAgentMain {
    // 智谱GLM API密钥,提交博客时可以保留,或者自行替换
    private static final String API_KEY = "e1a64530111046149dee3ec0f15c62b0.3Rn1mCCug3p4Q8Sw";
    private static final String API_URL = "https://open.bigmodel.cn/api/paas/v4/chat/completions";

    // 内存存储待办列表
    private static final List<String> todoList = new ArrayList<>();

    public static void main(String[] args) {
        System.out.println("===== 待办智能体启动 =====");
        System.out.println("支持:添加待办、查看待办、删除待办");
        System.out.println("输入 exit 退出程序");
        BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));

        while (true) {
            try {
                System.out.print("请输入指令:");
                String userInput = consoleReader.readLine();
                if (userInput == null || userInput.equalsIgnoreCase("exit")) {
                    System.out.println("程序退出");
                    break;
                }
                String llmCommand = callLLM(userInput);
                System.out.println("模型返回指令:" + llmCommand);
                String result = handleToolCommand(llmCommand);
                System.out.println("执行结果:" + result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 工具指令分发处理函数
     * @param cmd 大模型返回指令 ADD|xxx / LIST / DEL|num
     * @return 执行反馈文本
     */
    public static String handleToolCommand(String cmd) {
        if (cmd.startsWith("ADD|")) {
            String todoContent = cmd.substring(4);
            todoList.add(todoContent);
            return "✅ 添加成功:" + todoContent;
        } else if (cmd.equals("LIST")) {
            if (todoList.isEmpty()) {
                return "📋 待办列表:暂无待办";
            }
            StringBuilder sb = new StringBuilder("📋 待办列表:\n");
            for (int i = 0; i < todoList.size(); i++) {
                sb.append(i).append(" - ").append(todoList.get(i)).append("\n");
            }
            return sb.toString().trim();
        } else if (cmd.startsWith("DEL|")) {
            String numStr = cmd.substring(4);
            try {
                int index = Integer.parseInt(numStr);
                if (index >= 0 && index < todoList.size()) {
                    String removed = todoList.remove(index);
                    return "✅ 删除成功:" + removed;
                } else {
                    return "❌ 序号不存在";
                }
            } catch (NumberFormatException e) {
                return "❌ DEL后面不是合法数字";
            }
        } else {
            return "⚠️ 无法识别指令";
        }
    }

    /**
     * 调用智谱GLM大模型接口
     * @param userMsg 用户输入自然语言
     * @return 模型输出的标准化工具指令
     */
    public static String callLLM(String userMsg) {
        String systemPrompt = "你是待办事项智能助手。你只能输出下面固定格式指令,不能额外解释、不能闲聊。规则:1.用户添加待办:输出ADD|任务内容;2.用户查看待办:输出LIST;3.用户删除待办:输出DEL|序号(序号从0开始)。禁止输出任何其他文字!";

        String reqBody = "{" +
                "\"model\":\"glm-4-flash\"," +
                "\"messages\":[" +
                "{\"role\":\"system\",\"content\":\"" + systemPrompt.replace("\"", "\\\"") + "\"}," +
                "{\"role\":\"user\",\"content\":\"" + userMsg.replace("\"", "\\\"") + "\"}" +
                "]," +
                "\"temperature\":0.1" +
                "}";

        try {
            URL url = new URL(API_URL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);

            OutputStream os = conn.getOutputStream();
            os.write(reqBody.getBytes(StandardCharsets.UTF_8));
            os.close();

            int code = conn.getResponseCode();
            BufferedReader reader;
            if (code == 200) {
                reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            } else {
                reader = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
            }
            StringBuilder respSb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                respSb.append(line);
            }
            reader.close();
            conn.disconnect();

            String fullJson = respSb.toString();
            System.out.println("【DEBUG 原始JSON】:" + fullJson);

            String searchKey = "\"content\":\"";
            int contentStart = fullJson.indexOf(searchKey);
            if (contentStart == -1) {
                return "解析失败,找不到content";
            }
            contentStart += searchKey.length();

            int contentEnd = contentStart;
            while (true) {
                contentEnd = fullJson.indexOf("\"", contentEnd);
                if (contentEnd <= 0) break;
                int backSlashCount = 0;
                int checkPos = contentEnd - 1;
                while (checkPos >= 0 && fullJson.charAt(checkPos) == '\\') {
                    backSlashCount++;
                    checkPos--;
                }
                if (backSlashCount % 2 == 0) {
                    break;
                }
                contentEnd += 1;
            }

            if (contentEnd < contentStart) {
                return "解析失败";
            }
            String reply = fullJson.substring(contentStart, contentEnd);
            reply = reply.replace("\\n", "\n").replace("\\\"", "\"");
            return reply.trim();

        } catch (Exception e) {
            e.printStackTrace();
            return "网络请求异常";
        }
    }
}
四、使用示例(功能演示)
在这里上传 3 张控制台运行截图:
图 1:添加待办演示:输入【帮我晚上复习软件工程作业】,ADD 执行成功
![4f9ad02c3c1c8a4ff025907c17560d7d](https://img2024.cnblogs.com/blog/3850325/202610/3850325-20261023183125775-1423717766.png)

图 2:查询待办演示:输入【看看我所有待办】,LIST 展示列表
![25102bdb9309e46bbdf500aa37c00e47](https://img2024.cnblogs.com/blog/3850325/202610/3850325-20261023183305305-1636508455.png)

图 3:删除待办演示:输入【把第 0 条删掉】,DEL 删除成功
![7ff2adea82a602f549fa992dd35c3d3a](https://img2024.cnblogs.com/blog/3850325/202610/3850325-20261023183328930-268295643.png)

演示文字说明:
输入:帮我晚上复习软件工程作业 → 模型返回ADD|晚上复习软件工程作业,添加成功
输入:看看我所有待办 → 模型返回LIST,打印待办清单
输入:把第 0 条删掉 → 模型返回DEL|0,删除对应待办

五、测试结果   
![image](https://img2024.cnblogs.com/blog/3850325/202610/3850325-20261023221846904-256398787.png)

六、GitHub仓库链接
https://github.com/Yimulamu/MCP-TodoAgent-Java
七、项目总结
本次项目实现了一个简易 MCP 待办智能体,使用原生 Java,不引入 Maven。我们小组分工协作,完成需求分析、架构设计、代码开发、调试测试与文档撰写。
项目实现了大模型自然语言理解和本地工具调用分离的思想,理解了 MCP 智能体的运行模式。
项目不足:数据只保存在内存,重启程序数据丢失;后续可以拓展持久化存储、图形界面 GUI 等功能。
八、心得体会
通过本次软件工程小组作业,组员熟悉了团队分工开发流程,理解了需求、设计、编码、测试完整软件开发流程,掌握了大模型智能体工具调用的实现思路,提升了 Java 代码调试和协作开发的能力。
posted @ 2026-10-24 00:17  依木拉木  阅读(18)  评论(0)    收藏  举报