Java学习进程16
发布时间:2026/11/4 7:07:25 锦皓数字建站

Java Agent 开发Agent 入门1.Agent 与基座模型Agent智能体是能够根据用户需求进行判断并结合工具完成任务的智能程序。基座模型是 Agent 的核心语言模型负责理解用户输入、分析问题并生成回答。可看作百科全书或人的大脑。基座模型负责理解、分析和生成内容。Agent在基座模型的基础上进一步组织任务、调用工具。外部工具为 Agent 提供模型本身不直接具备的操作能力例如获取当前日期、读取本地文件和检查代码。2.使用 Java 调用大模型 API使用 DeepSeek API通过 HTTP 请求向大模型发送消息再获取模型返回的文本。主要涉及技术 作用 HashMap 保存模型请求参数 List 保存消息列表 ObjectMapper 将 Java 对象转换为 JSON并解析 JSON HttpClient 创建 HTTP 客户端 HttpRequest 构造 API 请求 HttpResponse 接收服务器响应 JsonNode 读取 JSON 响应中的字段核心代码流程packagecom.agent;importcom.fasterxml.jackson.core.JsonProcessingException;importcom.fasterxml.jackson.databind.JsonNode;importcom.fasterxml.jackson.databind.ObjectMapper;importjava.net.URI;importjava.net.http.HttpClient;importjava.net.http.HttpRequest;importjava.net.http.HttpResponse;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Objects;/** * author YAN * date 2026/10/24 19:08 * description * Agent:豆包,workBuddy,chatGPT * 基座模型:一本百科全书人的大脑(deepseek,千问) */publicclassMAgent{publicstaticvoidmain(String[]args){try{chat();}catch(Exceptione){thrownewRuntimeException(e);}}staticStringAPI_KEYsk-1412e45194d440168e28c96484c692fe;staticStringURLhttps://api.deepseek.com/chat/completions;//链接deepseek模型实现文本聊天publicstaticvoidchat()throwsException{//利用哈希表保存数据创建请求参数HashMapString,ObjecthmnewHashMap();hm.put(model,deepseek-flash);//创建消息ListHashMapString,StringhashMapListnewArrayList();HashMapString,StringmsgHmnewHashMap();msgHm.put(role,user);msgHm.put(content,风铃玉怎么养护会更出状态);hashMapList.add(msgHm);hm.put(messages,hashMapList);//把hm对象转成json格式的字符串数据//ObjectMapperObjectMappermappernewObjectMapper();Stringjsonmapper.writeValueAsString(hm);//给大模型服务器发送请求//创建 HTTP 客户端对象HttpClientclientHttpClient.newHttpClient();//请求对象绑定数据HttpRequestrequestHttpRequest.newBuilder().uri(URI.create(URL)).header(Content-Type,application/json).header(Authorization,Bearer API_KEY).POST(HttpRequest.BodyPublishers.ofString(json)).build();//发送请求并且得到响应对象HttpResponseStringresponseclient.send(request,HttpResponse.BodyHandlers.ofString());//通过响应对象提取大模型返回数据JsonNoderootmapper.readTree(response.body());System.out.println(root:root);Stringmsgroot.path(choices).get(0).path(message).path(content).asText();System.out.println(AI:msg);}}其中API_KEY 是访问模型服务的密钥URL 是模型接口地址。实际使用时应将密钥妥善保管不要直接提交到公开代码仓库。3.实现连续对话通过控制台输入语句实现与大模型的连续对话。publicstaticvoidmain(String[]args){try{ScannerscannewScanner(System.in);while(true){System.out.println(用户);Stringpromptscan.nextLine();chat(prompt);}}catch(Exceptione){thrownewRuntimeException(e);}}这里通过 Scanner 获取用户输入通过循环持续调用 chat() 方法。Agent 功能拓展1.从普通聊天到工具调用第一阶段的 Agent 主要负责向大模型发送问题并获取回答。第二阶段开始让 Agent 结合外部工具获取实时信息例如获取当前日期。获取当前时间。获取天气信息。读取本地代码并检查、修复错误。核心思想是大模型负责判断用户意图Java 程序负责执行具体操作。例如用户询问当前日期时程序可以先让模型判断用户是否在询问日期。如果模型返回约定的标识Java 程序再调用本地日期方法。2.使用自定义方法获取日期使用 LocalDate 获取系统当前日期importjava.time.LocalDate;publicstaticStringgetTime(){LocalDatedateLocalDate.now();returndate.toString();}LocalDate.now() 返回当前系统日期toString() 将日期转换为字符串。另该方法获取的是日期并不包含具体时分秒。若要获取时间需要使用相应的时间 API天气信息则需要接入相应的外部服务。3.通过提示词约定模型输出使用提示词要求模型在特定情况下返回指定格式Stringinput 用户问题%s 严格根据规制回答问题 1.如果用户问今天日期不要直接输出日期 输出内容日期 回答问题简洁不啰嗦 .formatted(prompt);之后Java 程序根据模型返回的内容进行判断if(resp.startsWith(日期)){StringtimegetTime();StringtimePrompt 用户问题%s 时间信息%s 只需要回答日期或时间不啰嗦 .formatted(prompt,time);Stringtmsend(timePrompt);System.out.println(AI:tm);}else{System.out.println(AI:resp);stringBuilder.append(resp);}Agent 代码检查功能1.功能目标将 Agent 从信息问答扩展为本地代码辅助工具主要完成根据指定位置检查代码是否存在错误。将代码内容发送给大模型分析。向用户展示错误提示。询问用户是否需要 AI 修改代码。获取模型生成的修改后代码。2.读取本地代码文件使用 File、FileReader 和 BufferedReader 读取文件。StringfilePath链接地址filename;//创建字符输入流读取代码文件FileReaderfirnewFileReader(newFile(filePath));BufferedReaderbrnewBufferedReader(fir);//保存读取到的源代码StringBuildercodeStrnewStringBuilder();Stringline;//读取一行代码不空就一直读while((linebr.readLine())!null){codeStr.append(line\r\n);}System.out.println(codeStrcodeStr);实现过程File表示指定路径的文件。FileReader读取文本文件内容。BufferedReader按行读取文本。StringBuilder将读取到的多行代码拼接起来。3.将源代码交给大模型检查读取文件后通过提示词要求模型检查代码。//设置提示词StringcodePrompt 你是一个专业程序员帮我检查下面这段代码是否存在错误 源代码%s 如果有错误。返回错误信息 如果没有错误就直接说代码没有明显错误 .formatted(codeStr);StringcodeRespsend(codePrompt);System.out.println(错误提示:codeResp);这里的 send() 是之前封装的大模型 API 请求方法这样可以复用已有的模型调用逻辑而不必在代码检查功能中重复编写 HTTP 请求和 JSON 解析代码。4.由用户决定是否修改代码通过控制台询问用户System.out.println(是否需要AI修改代码(y/n));ScannerscannewScanner(System.in);Stringtypescan.nextLine();//equalsIgnoreCase() 该判断方法可忽略大小写if(y.equalsIgnoreCase(type)){Stringprompt 修改源代码中的错误只保留源代码 不要显示 源代码%s .formatted(codeStr);Stringcodesend(prompt);System.out.println(code:code);equalsIgnoreCase() 用于忽略大小写进行字符串比较因此输入 y 或 Y 都可以进入修改分支。Agent 代码重构由于前面几个版本将对话、模型调用、日期判断和代码检查等逻辑集中在 MAgent 中。随着工具数量增加若继续把所有功能写在同一个类中会导致类的职责越来越多新增工具时需要不断修改原有代码工具逻辑和对话逻辑耦合代码维护和功能扩展更加困难。因此将工具抽象为统一接口通过工具注册中心管理工具并由 Agent 根据模型返回的结果调用相应工具。1.设计 Tool 接口将每一种外部工具设计为统一的接口packagecom.agent1102;/** * author YAN * date 2026/11/2 11:43 * description 接口起到的作用规范工具类的设计 */publicinterfaceTool{//工具名publicStringname();//工具的描述publicStringdesc();//工具的实现publicStringexecute(Stringmsg)throwsException;}接口中定义了三个方法通过接口统一规范不同工具可以采用不同的内部实现方式但对外提供相同的方法结构。2.实现具体工具类CodeCheck 类实现了 Tool 接口packagecom.agent1102;importjava.io.BufferedReader;importjava.io.File;importjava.io.FileReader;importjava.util.Scanner;/** * author YAN * date 2026/11/2 11:49 * description 修复代码文件的工具类 */publicclassCodeCheckimplementsTool{OverridepublicStringname(){return代码检查;}OverridepublicStringdesc(){return如果桌面代码文件检查错误并修改;}OverridepublicStringexecute(Stringmsg)throwsException{StringfilePath链接地址msg;//后续实现读取文件、检查错误和修改代码的功能//字符流读取代码文件FileReaderfirnewFileReader(newFile(filePath));BufferedReaderbrnewBufferedReader(fir);StringBuildercodeStrnewStringBuilder();Stringline;//读取一行代码不空就一直读while((linebr.readLine())!null){codeStr.append(line\r\n);}System.out.println(codeStrcodeStr);//设置提示词StringcodePrompt 你是一个专业程序员帮我检查下面这段代码是否存在错误 源代码%s 如果有错误。返回错误信息 如果没有错误就直接说代码没有明显错误 .formatted(codeStr);StringcodeRespMAgent.send(codePrompt);System.out.println(是否需要AI修改代码(y/n));ScannerscannewScanner(System.in);Stringtypescan.nextLine();//equalsIgnoreCase() 该判断方法可忽略大小写if(y.equalsIgnoreCase(type)){Stringprompt 修改源代码中的错误只保留源代码 不要显示 源代码%s .formatted(codeStr);StringcodeMAgent.send(prompt);System.out.println(code:code);//把修改后的代码再写入文件}return;}}代码中 msg 用于传递文件名 execute() 负责执行具体工具逻辑而 Agent 不需要了解文件读取的全部细节。3.设计 ToolRegister 工具注册中心使用 ToolRegister 统一管理工具对象。packagecom.agent1102;importjava.util.ArrayList;importjava.util.List;/** * author YAN * date 2026/11/2 11:55 * description 工具的注册中心 */publicclassToolRegister{//获取所有工具的方法publicstaticListToolgetAllTool(){ListTooltoolsnewArrayList();tools.add(newCodeCheck());returntools;}}后续如果新增功能可以在相应的工具类实现 Tool 接口再将工具加入注册中心。Agent 就可以统一获取可用工具而不需要在对话逻辑中逐一创建各种工具对象。4.Agent 如何选择并调用工具在重构后的 MAgent 中首先获取全部工具再将工具名称和描述提供给大模型。获取所有工具并整理工具信息publicstaticvoidchat(Stringprompt)throwsException{StringBuildertoolMsgnewStringBuilder();//遍历出所有的工具类发给大模型让它知道可以调用哪些工具for(Tooltool:ToolRegister.getAllTool()){toolMsg.append([工具名).append(tool.name()).append(]).append( 工具描述).append(tool.desc()).append(\n);}System.out.println(toolMsg: toolMsg);通过提示词让大模型判断是否调用工具Stringinput 你是一个智能助手能使用一下工具 s 用户问题%s 规则 1.如果需要使用工具 输出 工具#参数 2.如果不要使用工具就直接回答 回答问题简洁不啰嗦 .formatted(toolMsg,prompt);将工具名称、工具描述和用户问题一起发送给大模型让模型根据用户需求判断是否需要使用工具。根据模型返回结果调用对应工具//更高效的拼接字符串方法stringBuilder.append(input);//响应结果Stringrespsend(stringBuilder.toString());System.out.println(resp:resp);//根据响应结果调用对应的工具String[]toolArrresp.split(:);//根据响应结果遍历所有的工具for(Tooltool:ToolRegister.getAllTool()){if(toolArr[0].equals(tool.name())){System.out.println(toolArr[0]:toolArr[1]);tool.execute(toolArr[1]);return;}}System.out.println(AI:resp);stringBuilder.append(resp);}程序通过split(“#”) 将返回内容拆分toolArr[0]:工具名称即“代码检查”toolArr[1]:工具参数然后遍历注册中心中的工具找到名称匹配的工具调用其 execute() 方法。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。