ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java智能体开发实战:从零构建任务执行与协调系统

Java智能体开发实战:从零构建任务执行与协调系统 最近在整理大三下学期的项目经历时发现很多同学对“智能体”这个概念既好奇又觉得无从下手尤其是在Java技术栈下如何落地一个完整的智能体项目。网上资料要么过于理论化要么是Python生态的专属教程对于Java开发者来说缺乏一套从零到一、可复现的实战指南。本文将分享一个基于Java技术栈独立开发的智能体项目全流程涵盖从核心概念理解、技术选型、环境搭建、核心模块开发到最终部署上线的完整闭环。无论你是想为简历增加一个亮眼的项目还是希望深入理解AI应用开发都能从本文中找到清晰的路径和可运行的代码。1. 智能体项目概念、价值与技术选型在开始编码之前我们必须先厘清几个核心问题什么是智能体为什么用Java来开发以及我们这个项目要做什么。1.1 智能体Agent是什么在AI领域智能体通常指一个能够感知环境、进行决策并执行动作以达成目标的自治系统。它不仅仅是调用一个API生成文本而是具备记忆、规划、工具使用等能力的程序实体。一个典型的智能体工作流程可以简化为感知接收用户输入或环境状态。思考基于内部记忆和知识进行推理、规划。行动调用工具如搜索、计算、写文件或生成回复。学习根据行动结果更新内部状态。与我们熟悉的“ChatGPT对话”不同智能体更强调自主性和目标导向性。例如一个“旅行规划智能体”不仅能回答景点信息还能主动查询天气、对比机票价格、生成日程表并预订酒店。1.2 为什么选择Java技术栈当前智能体开发的热门工具如LangChain、LlamaIndex确实以Python为主。但选择Java有独特的优势工程化优势Java在大型企业级应用开发中在并发处理、内存管理、代码结构规范性方面有深厚积累。对于需要高可靠、易维护的智能体应用Java是绝佳选择。生态整合如果你的现有业务系统如Spring Boot微服务是Java技术栈用Java开发智能体可以无缝集成避免跨语言调用的复杂度。性能与稳定性JVM的成熟GC机制和JIT优化对于需要长时间运行、处理复杂逻辑的智能体服务至关重要。学习与挑战用Java探索AI前沿能让你同时巩固后端工程能力和理解AI应用架构提升综合竞争力。1.3 项目目标一个任务执行与协调智能体我们的项目将构建一个“多任务协调智能体”。它的核心能力是理解复杂指令将用户模糊的自然语言指令如“帮我安排下周的学习计划并查一下杭州的天气”分解为明确的子任务。调度与执行自主调用不同的工具如日历管理、天气查询、文档总结来完成子任务。汇总与回复整合各工具的执行结果生成结构清晰、用户友好的最终答复。技术栈规划如下核心框架Spring Boot 3.x (提供Web服务和依赖注入)AI能力集成通过HTTP Client调用大模型API如OpenAI GPT、国内大模型工具层封装各类功能为可被智能体调用的“工具”Tool记忆与状态管理使用Redis或数据库存储对话历史与任务状态任务编排引擎自定义轻量级状态机或使用Flowable等引擎管理任务流2. 开发环境与项目初始化工欲善其事必先利其器。一个清晰的项目结构是成功的第一步。2.1 环境准备清单请确保你的开发环境包含以下组件JDK17或以上版本推荐Amazon Corretto 17或OpenJDK 17构建工具Maven 3.6 或 Gradle 7.xIDEIntelliJ IDEA社区版即可或 VS Code with Java插件依赖管理Maven中央仓库访问正常可选组件Docker用于容器化部署、Redis用于状态缓存2.2 使用Spring Initializr创建项目通过 start.spring.io 快速生成项目骨架。项目元数据Project: MavenLanguage: JavaSpring Boot: 3.2.5 (选择稳定版本)Group: com.exampleArtifact: java-agent-demoPackaging: JarJava: 17依赖选择Spring Web提供RESTful API接口。Spring Data Redis用于智能体的记忆存储和会话管理。Lombok减少样板代码但需注意IDE插件配置。Validation参数校验。点击“GENERATE”下载压缩包并解压用IDE打开。2.3 项目结构规划创建清晰的多模块或分包结构有助于代码管理。以下是建议的包结构src/main/java/com/example/javaagentdemo/ ├── JavaAgentDemoApplication.java # 主启动类 ├── config/ # 配置类 │ ├── RedisConfig.java │ └── WebClientConfig.java # 用于调用外部API ├── controller/ # 控制器层 │ └── AgentController.java ├── service/ # 业务逻辑层 │ ├── AgentCoreService.java # 智能体核心调度逻辑 │ ├── llm/ # 大模型服务封装 │ │ ├── LLMService.java │ │ └── impl/OpenAIServiceImpl.java │ └── tool/ # 工具层 │ ├── Tool.java # 工具接口 │ ├── WeatherTool.java │ ├── CalculatorTool.java │ └── TodoManagerTool.java ├── entity/ # 实体类 │ ├── AgentMessage.java # 消息实体 │ └── Task.java # 任务实体 ├── repository/ # 数据访问层如需持久化 │ └── ConversationRepository.java └── dto/ # 数据传输对象 ├── AgentRequest.java └── AgentResponse.java在pom.xml中我们还需要手动添加一些依赖例如用于HTTP调用的Apache HttpClient或Spring的WebClient以及JSON处理库Spring Boot已包含Jackson。!-- 在Spring Initializr生成的依赖基础上可选择性添加 -- dependency groupIdorg.apache.httpcomponents.client5/groupId artifactIdhttpclient5/artifactId version5.3/version /dependency !-- 如果使用WebClientspring-boot-starter-webflux 已包含但通常Web模块用RestTemplate或第三方客户端 -- !-- 推荐使用OkHttp -- dependency groupIdcom.squareup.okhttp3/groupId artifactIdokhttp/artifactId version4.12.0/version /dependency3. 核心模块一大模型能力集成智能体的“大脑”依赖于大语言模型。我们将封装一个通用的LLM服务便于切换不同供应商。3.1 设计LLM服务接口首先定义接口抽象出调用过程。// file: src/main/java/com/example/javaagentdemo/service/llm/LLMService.java package com.example.javaagentdemo.service.llm; import com.example.javaagentdemo.dto.ChatMessage; import java.util.List; public interface LLMService { /** * 调用大模型聊天补全接口 * param messages 对话历史消息 * param temperature 温度参数控制随机性 * return 模型返回的文本内容 */ String chatCompletion(ListChatMessage messages, Double temperature); /** * 简化调用使用默认参数 */ String chatCompletion(ListChatMessage messages); }3.2 实现OpenAI API调用以OpenAI GPT-3.5/4为例实现上述接口。你需要准备一个有效的API Key。// file: src/main/java/com/example/javaagentdemo/service/llm/impl/OpenAIServiceImpl.java package com.example.javaagentdemo.service.llm.impl; import com.example.javaagentdemo.dto.ChatMessage; import com.example.javaagentdemo.service.llm.LLMService; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.List; Service Slf4j public class OpenAIServiceImpl implements LLMService { private static final MediaType JSON MediaType.get(application/json; charsetutf-8); Value(${openai.api.key}) private String apiKey; Value(${openai.api.url:https://api.openai.com/v1/chat/completions}) private String apiUrl; Value(${openai.model:gpt-3.5-turbo}) private String model; private final OkHttpClient client new OkHttpClient(); private final ObjectMapper objectMapper new ObjectMapper(); Override public String chatCompletion(ListChatMessage messages, Double temperature) { // 1. 构建请求体 OpenAiRequest requestBody new OpenAiRequest(model, messages, temperature); String jsonBody; try { jsonBody objectMapper.writeValueAsString(requestBody); } catch (Exception e) { log.error(序列化请求体失败, e); return 请求构造失败; } // 2. 构建HTTP请求 Request request new Request.Builder() .url(apiUrl) .addHeader(Authorization, Bearer apiKey) .addHeader(Content-Type, application/json) .post(RequestBody.create(jsonBody, JSON)) .build(); // 3. 发送请求并处理响应 try (Response response client.newCall(request).execute()) { if (!response.isSuccessful()) { log.error(OpenAI API调用失败状态码: {}, 响应体: {}, response.code(), response.body() ! null ? response.body().string() : 空); return 大模型服务调用异常状态码 response.code(); } if (response.body() null) { return 收到空响应; } String responseBody response.body().string(); OpenAiResponse openAiResponse objectMapper.readValue(responseBody, OpenAiResponse.class); if (openAiResponse.choices ! null !openAiResponse.choices.isEmpty()) { return openAiResponse.choices.get(0).message.content; } else { return 模型未返回有效内容; } } catch (IOException e) { log.error(调用OpenAI API时发生IO异常, e); return 网络或服务异常; } } Override public String chatCompletion(ListChatMessage messages) { return chatCompletion(messages, 0.7); // 默认温度值 } // 内部类用于映射OpenAI请求和响应格式 lombok.Data private static class OpenAiRequest { private final String model; private final ListChatMessage messages; private final Double temperature; } lombok.Data private static class OpenAiResponse { private ListChoice choices; lombok.Data static class Choice { private ChatMessage message; } } }对应的消息实体和配置// file: src/main/java/com/example/javaagentdemo/dto/ChatMessage.java package com.example.javaagentdemo.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; Data NoArgsConstructor AllArgsConstructor public class ChatMessage { private String role; // system, user, assistant private String content; }在application.yml中配置你的API Key# file: src/main/resources/application.yml openai: api: key: ${OPENAI_API_KEY:your-api-key-here} # 建议使用环境变量 url: https://api.openai.com/v1/chat/completions model: gpt-3.5-turbo spring: data: redis: host: localhost port: 6379 # password: 如果有密码则配置关键点说明安全性API Key绝不能硬编码在代码中提交到版本库。使用环境变量${OPENAI_API_KEY}或配置中心管理。容错性网络请求必须包含超时设置和异常处理。上述示例简化了生产环境应配置OkHttpClient的超时参数并考虑重试机制。模型切换通过配置项openai.model可以轻松切换不同的模型如gpt-4。4. 核心模块二可扩展的工具Tool系统工具是智能体的“手脚”。我们需要设计一个系统让智能体能够发现、描述并调用各种功能。4.1 定义工具接口与基类首先定义一个所有工具都必须实现的接口。// file: src/main/java/com/example/javaagentdemo/service/tool/Tool.java package com.example.javaagentdemo.service.tool; import com.fasterxml.jackson.databind.JsonNode; /** * 智能体工具接口。 * 每个工具必须提供名称、描述、参数schema并实现执行方法。 */ public interface Tool { /** * 工具的唯一名称用于智能体识别和调用。 */ String getName(); /** * 工具的自然语言描述用于让大模型理解工具的功能。 */ String getDescription(); /** * 工具的输入参数JSON Schema定义。 * 用于让大模型知道调用此工具需要提供哪些参数。 * return 符合JSON Schema格式的JsonNode */ JsonNode getParametersSchema(); /** * 执行工具的核心方法。 * param arguments 调用参数通常是一个JSON字符串或对象。 * return 工具执行结果的文本描述。 */ String execute(String arguments); }提供一个抽象基类简化参数Schema的定义// file: src/main/java/com/example/javaagentdemo/service/tool/BaseTool.java package com.example.javaagentdemo.service.tool; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; RequiredArgsConstructor public abstract class BaseTool implements Tool { protected final ObjectMapper objectMapper; protected final String name; protected final String description; Override public String getName() { return name; } Override public String getDescription() { return description; } /** * 构建一个简单的参数Schema。 * 子类可以重写此方法以提供更复杂的Schema。 * param properties 参数属性定义 * return JsonNode格式的Schema */ protected JsonNode buildSimpleSchema(ObjectNode properties) { ObjectNode schema objectMapper.createObjectNode(); schema.put(type, object); schema.set(properties, properties); schema.putArray(required).addAll(() - properties.fieldNames()); return schema; } }4.2 实现具体工具天气查询让我们实现一个具体的工具它调用一个免费的天气API。// file: src/main/java/com/example/javaagentdemo/service/tool/WeatherTool.java package com.example.javaagentdemo.service.tool; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.IOException; Component Slf4j public class WeatherTool extends BaseTool { private final OkHttpClient client new OkHttpClient(); Value(${weather.api.key:}) // 可从配置读取示例使用公开API private String apiKey; private static final String API_URL https://api.openweathermap.org/data/2.5/weather; public WeatherTool(ObjectMapper objectMapper) { super(objectMapper, get_weather, 获取指定城市的当前天气情况。); } Override public JsonNode getParametersSchema() { // 定义参数city字符串类型必填 ObjectNode properties objectMapper.createObjectNode(); ObjectNode cityParam objectMapper.createObjectNode(); cityParam.put(type, string); cityParam.put(description, 城市名称例如Beijing, Shanghai); properties.set(city, cityParam); return buildSimpleSchema(properties); } Override public String execute(String arguments) { try { JsonNode argsNode objectMapper.readTree(arguments); String city argsNode.get(city).asText(); if (city null || city.trim().isEmpty()) { return 错误未提供城市参数。; } // 构建请求URL (使用公开API无需key仅作演示) String url String.format(%s?q%sappid%sunitsmetriclangzh_cn, API_URL, city, apiKey); Request request new Request.Builder().url(url).build(); try (Response response client.newCall(request).execute()) { if (!response.isSuccessful()) { return String.format(获取天气失败HTTP状态码%d, response.code()); } if (response.body() null) { return 天气API返回空响应。; } String responseBody response.body().string(); JsonNode weatherData objectMapper.readTree(responseBody); // 解析并格式化天气信息 String cityName weatherData.path(name).asText(); String description weatherData.path(weather).get(0).path(description).asText(); double temp weatherData.path(main).path(temp).asDouble(); double feelsLike weatherData.path(main).path(feels_like).asDouble(); int humidity weatherData.path(main).path(humidity).asInt(); return String.format(城市%s\n天气状况%s\n当前温度%.1f°C\n体感温度%.1f°C\n湿度%d%%, cityName, description, temp, feelsLike, humidity); } } catch (IOException e) { log.error(调用天气API异常, e); return 查询天气服务时发生网络错误。; } catch (Exception e) { log.error(处理天气请求参数异常, e); return 处理请求参数时发生错误。; } } }4.3 工具注册与管理我们需要一个中心化的注册表来管理所有可用工具。// file: src/main/java/com/example/javaagentdemo/service/tool/ToolRegistry.java package com.example.javaagentdemo.service.tool; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.List; import java.util.Map; Component public class ToolRegistry { private final MapString, Tool toolMap new HashMap(); private final ListTool tools; // 通过构造器注入所有Tool Bean public ToolRegistry(ListTool tools) { this.tools tools; } PostConstruct public void init() { for (Tool tool : tools) { toolMap.put(tool.getName(), tool); System.out.println(已注册工具: tool.getName() - tool.getDescription()); } } public Tool getTool(String name) { return toolMap.get(name); } public MapString, Tool getAllTools() { return new HashMap(toolMap); } /** * 获取所有工具的“描述”用于构建给大模型的系统提示。 */ public String getToolsDescriptionForPrompt() { StringBuilder sb new StringBuilder(); sb.append(你可以使用以下工具\n); for (Tool tool : tools) { sb.append(- ).append(tool.getName()).append(: ).append(tool.getDescription()) .append( 参数要求: ).append(tool.getParametersSchema().toString()).append(\n); } sb.append(当你需要调用工具时请严格按照工具要求的参数格式以JSON对象形式提供。); return sb.toString(); } }5. 核心模块三智能体调度引擎这是项目的“中枢神经系统”负责协调大模型思考和工具调用。5.1 设计智能体工作流一个简化的智能体单次循环流程如下接收用户输入结合对话历史形成完整的上下文。构建系统提示包含工具描述、执行格式要求等。调用大模型让模型根据上下文决定是直接回答还是调用工具。解析模型响应判断响应是自然语言还是工具调用指令。执行工具如果是指令则调用对应工具并获取结果。组织回复将工具结果返回给用户或作为新的上下文继续循环。5.2 实现核心调度服务// file: src/main/java/com/example/javaagentdemo/service/AgentCoreService.java package com.example.javaagentdemo.service; import com.example.javaagentdemo.dto.ChatMessage; import com.example.javaagentdemo.service.llm.LLMService; import com.example.javaagentdemo.service.tool.Tool; import com.example.javaagentdemo.service.tool.ToolRegistry; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; Service Slf4j public class AgentCoreService { Autowired private LLMService llmService; Autowired private ToolRegistry toolRegistry; Autowired private ObjectMapper objectMapper; // 系统提示词定义了智能体的角色和能力 private static final String SYSTEM_PROMPT_TEMPLATE 你是一个有帮助的AI助手可以调用工具来解决问题。 %s 请根据用户的问题决定是直接回答还是调用工具。 如果你决定调用工具你的响应必须是严格的JSON格式且只包含以下两个字段 1. action: 固定为 tool_call 2. tool: 工具的名称 3. arguments: 一个JSON对象包含调用该工具所需的参数 例如调用天气工具{action: tool_call, tool: get_weather, arguments: {city: 北京}} 如果你不需要调用工具请直接给出自然语言回答。 ; /** * 处理一轮用户对话 * param userInput 用户输入 * param conversationHistory 对话历史可为空 * return 智能体的回复 */ public String processUserInput(String userInput, ListChatMessage conversationHistory) { // 1. 准备对话历史 ListChatMessage messages new ArrayList(); // 添加系统提示 String systemPrompt String.format(SYSTEM_PROMPT_TEMPLATE, toolRegistry.getToolsDescriptionForPrompt()); messages.add(new ChatMessage(system, systemPrompt)); // 添加上下文历史 if (conversationHistory ! null) { messages.addAll(conversationHistory); } // 添加当前用户输入 messages.add(new ChatMessage(user, userInput)); // 2. 调用大模型 String llmResponse llmService.chatCompletion(messages, 0.2); // 低温度减少随机性 // 3. 解析响应判断是否为工具调用 try { JsonNode responseJson objectMapper.readTree(llmResponse); if (responseJson.has(action) tool_call.equals(responseJson.get(action).asText())) { // 是工具调用 String toolName responseJson.get(tool).asText(); JsonNode arguments responseJson.get(arguments); return handleToolCall(toolName, arguments.toString()); } } catch (Exception e) { // 响应不是JSON或解析失败视为自然语言回复 log.debug(LLM响应不是工具调用指令按自然语言处理: {}, llmResponse); } // 4. 如果是自然语言回复直接返回 return llmResponse; } private String handleToolCall(String toolName, String argumentsJson) { Tool tool toolRegistry.getTool(toolName); if (tool null) { return String.format(错误未知的工具 %s。, toolName); } try { log.info(调用工具: {} 参数: {}, toolName, argumentsJson); String toolResult tool.execute(argumentsJson); log.info(工具执行结果: {}, toolResult); // 这里可以将工具结果再次喂给LLM让LLM组织成对用户友好的语言。 // 简化处理直接返回结果 return 工具执行完成\n toolResult; } catch (Exception e) { log.error(执行工具 {} 时发生异常, toolName, e); return String.format(调用工具 %s 时发生错误%s, toolName, e.getMessage()); } } }5.3 提供REST API接口最后我们通过一个简单的Controller暴露服务。// file: src/main/java/com/example/javaagentdemo/controller/AgentController.java package com.example.javaagentdemo.controller; import com.example.javaagentdemo.dto.AgentRequest; import com.example.javaagentdemo.dto.AgentResponse; import com.example.javaagentdemo.service.AgentCoreService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/agent) Slf4j public class AgentController { Autowired private AgentCoreService agentCoreService; PostMapping(/chat) public AgentResponse chat(RequestBody AgentRequest request) { log.info(收到用户请求: {}, request.getMessage()); // 简化处理每次对话独立不维护历史。实际项目应使用session或userId维护对话历史。 String response agentCoreService.processUserInput(request.getMessage(), null); log.info(智能体回复: {}, response); return new AgentResponse(response); } } // file: src/main/java/com/example/javaagentdemo/dto/AgentRequest.java package com.example.javaagentdemo.dto; import lombok.Data; Data public class AgentRequest { private String message; private String sessionId; // 可用于关联对话历史 } // file: src/main/java/com/example/javaagentdemo/dto/AgentResponse.java package com.example.javaagentdemo.dto; import lombok.AllArgsConstructor; import lombok.Data; Data AllArgsConstructor public class AgentResponse { private String reply; }6. 运行、测试与效果演示6.1 启动项目确保Redis服务已启动如果使用了Redis存储会话。在项目根目录下运行mvn spring-boot:run # 或 java -jar target/java-agent-demo-0.0.1-SNAPSHOT.jar应用默认会在http://localhost:8080启动。6.2 使用API测试工具进行测试使用curl、Postman 或任何你喜欢的HTTP客户端进行测试。请求示例curl -X POST http://localhost:8080/api/agent/chat \ -H Content-Type: application/json \ -d {message: 今天北京天气怎么样}预期响应{ reply: 工具执行完成\n城市Beijing\n天气状况晴\n当前温度22.5°C\n体感温度21.0°C\n湿度45% }请求示例无需工具curl -X POST http://localhost:8080/api/agent/chat \ -H Content-Type: application/json \ -d {message: 你好请介绍一下你自己。}预期响应{ reply: 你好我是一个AI助手可以通过调用工具来帮助你查询天气、进行计算或管理任务等。有什么我可以帮你的吗 }6.3 项目效果与扩展方向至此一个具备基础能力的Java智能体项目就完成了。它能够理解用户意图。在需要时自主调用预定义的工具如天气查询。返回工具执行结果。你可以在此基础上进行大量扩展增加更多工具如计算器、日历管理、邮件发送、数据库查询等。实现对话记忆利用Redis存储ChatMessage历史实现多轮对话。复杂任务分解让大模型将复杂问题拆解成多个工具调用步骤并循环执行。前端界面使用Vue/React构建一个简单的聊天界面。部署上线使用Docker容器化部署到云服务器。7. 常见问题与排查思路在开发过程中你可能会遇到以下典型问题问题现象可能原因排查步骤与解决方案启动报错Failed to configure a DataSource引入了数据库依赖但未配置数据源。检查pom.xml中是否有多余的spring-boot-starter-data-jpa等依赖。如果不需要可排除或添加spring.datasource.url配置。调用OpenAI API超时或连接失败网络问题、API Key无效、服务地址错误。1. 检查网络连通性。2. 验证API Key是否正确且有余额。3. 检查application.yml中的openai.api.url配置。4. 在OkHttpClient中配置合理的超时时间。智能体不调用工具总是直接回复系统提示词Prompt设计不佳或模型温度参数过高。1. 检查SYSTEM_PROMPT_TEMPLATE确保指令清晰要求模型以JSON格式回复。2. 降低llmService.chatCompletion调用时的temperature值如设为0.1。3. 在Prompt中提供更详细、更强制性的工具调用示例。工具调用参数解析失败大模型返回的JSON格式不正确或参数类型不匹配。1. 打印出大模型的原始响应llmResponse检查其格式。2. 在handleToolCall方法中增加更健壮的JSON解析和校验。3. 在工具Schema中更精确地定义参数类型和描述。Lombok注解不生效IDE未安装Lombok插件或编译环境不支持。1. 在IntelliJ IDEA中安装Lombok插件并启用注解处理Settings - Build - Compiler - Annotation Processors。2. 确保pom.xml中Lombok依赖范围是provided或compile。3. 如果使用其他IDE或构建工具请参考Lombok官方文档进行配置。Redis连接失败Redis服务未启动或配置的主机/端口/密码错误。1. 运行redis-cli ping确认Redis服务是否运行。2. 检查application.yml中的spring.data.redis配置项。3. 如果不需要会话记忆功能可以先注释掉相关代码和依赖。8. 项目总结与进阶思考通过这个项目我们完成了一个Java智能体从零到一的搭建。它不仅是一个简单的API调用封装而是初步具备了感知-思考-行动的智能体核心循环。回顾核心收获架构清晰分离了LLM集成层、工具层和核心调度层符合单一职责原则易于维护和扩展。可扩展性强新的工具只需实现Tool接口并注册到ToolRegistry即可被智能体使用。工程化实践使用了Spring Boot的依赖注入、配置管理以及面向接口的编程代码质量更高。下一步可以深入的方向记忆与状态管理实现真正的多轮对话需要将会话历史、工具调用结果等状态持久化。可以考虑使用向量数据库存储历史实现长期记忆。流式响应当前是同步阻塞调用可以改造为SSE或WebSocket实现打字机式的流式输出体验更佳。工具编排与工作流当任务需要多个工具按顺序或条件执行时需要引入工作流引擎如Flowable、Camunda或自定义状态机来管理复杂的任务流。评估与监控为智能体的回答质量、工具调用成功率添加监控和评估指标这对于迭代优化至关重要。对接国内大模型将LLMService的实现替换为文心一言、通义千问、智谱GLM等国内模型的API调用注意调整请求和响应的数据格式。这个项目作为学习起点已经涵盖了智能体开发的核心模式。你可以将其作为毕业设计、个人作品集的一部分或者在此基础上不断迭代探索更复杂的AI应用场景。
返回列表