curd如何与agent结合
一、为什么 Java 后端不能只停留在增删改查
现在ai的能力越来越强,传统的纯后端项目已然不能吸引面试官的眼球,除非你的项目业务比较复杂,亮点比较多,硬实力比较强,所以我们要和ai agent结合起来,拥抱ai。
传统 Java 后端项目通常围绕数据增删改查展开:接收请求、校验参数、调用 Service、查询数据库、返回结果。这是后端开发的基本功,但如果项目只停留在这一层,很容易变成“接口搬运工”。
现在的业务系统越来越强调智能化:用户希望用自然语言表达需求,系统能够主动分析、检索资料、调用业务能力并给出结果。AI Agent 正是这种趋势下的后端能力扩展。
| CRUD 项目的典型特点 | 说明 |
| 输入明确 | 用户必须知道要调用哪个功能,前端必须按接口定义传固定参数。 |
| 流程固定 | 系统只能执行程序员提前写好的业务流程。 |
| 数据驱动 | 主要围绕数据库中的数据进行增删改查。 |
| 表达有限 | 接口返回结构化结果,但不能主动理解复杂意图。 |
普通 CRUD 接口示例
| @GetMapping("/user/{id}") public BaseResponse<UserVO> getUser(@PathVariable Long id) { UserVO userVO = userService.getUserById(id); return ResultUtils.success(userVO); } |
传统执行流程:
| 用户请求 ↓ Controller 接收参数 ↓ Service 处理业务逻辑 ↓ Mapper 查询数据库 ↓ 返回结果 |
升级后的目标
| 从“接口驱动”升级到“意图驱动”:用户不再必须知道接口细节,而是用自然语言表达目标,由 Agent 选择合适的工具和数据来源。 |
例如用户输入:“帮我分析最近三天的订单数据,并生成一份优化建议。”传统系统可能需要前端组合多个接口;Agent 则可以先理解需求,再调用订单查询工具,分析数据后生成建议。
二、传统 CRUD 与 AI Agent 的本质区别
| 对比项 | 传统 CRUD | AI Agent |
| 输入方式 | 固定参数、固定接口 | 自然语言、上下文输入 |
| 执行逻辑 | 代码中写死流程 | 模型判断意图,动态选择工具 |
| 数据来源 | 主要来自数据库 | 数据库、知识库、文件、外部 API |
| 输出结果 | JSON 或固定对象 | 文本、JSON、结构化对象、任务结果 |
| 核心难点 | 业务逻辑、SQL、接口设计 | Prompt、工具调用、RAG、权限和可观测性 |
| 面试亮点 | 基础开发能力 | AI 工程化和业务集成能力 |
AI Agent 不是简单的聊天机器人。它和普通大模型问答最大的区别是:Agent 可以根据用户意图决定是否调用工具、是否查询知识库、是否生成结构化结果,并把这些能力接入现有业务系统。
AI Agent 执行流程:
| 用户自然语言输入 ↓ Agent 理解用户意图 ↓ 判断是否需要查询知识库 ↓ 判断是否需要调用业务工具 ↓ 调用数据库 / API / 文件 / 第三方服务 ↓ 整合结果 ↓ 返回自然语言或结构化结果 |
三、AI Agent 的核心组成
一个可落地的 Java 后端 AI Agent,通常由以下能力组成:
| AI Agent = 大模型 + Prompt + 工具调用 + 知识库 + 记忆 + 业务系统 + 工程化控制 |
1. 大模型:负责理解和生成
大模型负责理解用户输入、生成回答、判断是否需要调用工具。Spring AI 中的 ChatClient 提供了和模型通信的流式 API,支持同步和流式调用。
-
Prompt:定义 Agent 的角色和规则
| 你是一个 Java 后端学习助手。 你的任务是帮助用户分析 Java 后端项目、解释面试题、生成学习计划。 回答时尽量结合 Spring Boot、MySQL、Redis、项目经验进行说明。 如果用户的问题需要查询项目数据,必须调用后端工具,不要编造。 |
在普通 CRUD 项目中,业务逻辑主要写在 Java 代码里;在 AI Agent 项目中,一部分行为约束会通过 Prompt 传给模型。但需要注意,Prompt 不是安全边界,真正的权限校验仍然要写在后端代码中。
-
Tool Calling:让模型调用后端能力
工具调用,也可以理解为函数调用。模型不会直接访问数据库或接口,而是提出“我需要调用某个工具”的请求,真正执行工具的是后端应用。工具可以是查询数据库、读取文件、创建任务、调用第三方服务等。
| @Component public class StudyTools { @Tool(description = "查询用户最近的 Java 后端错题") public List<WrongQuestionVO> getRecentWrongQuestions(Long userId) { return wrongQuestionService.listRecentWrongQuestions(userId); } @Tool(description = "为用户创建一条学习任务") public String createStudyTask(Long userId, String title, String description) { studyPlanService.createTask(userId, title, description); return "学习任务创建成功:" + title; } } |
-
RAG:让模型基于知识库回答
RAG 是 Retrieval Augmented Generation,中文常叫“检索增强生成”。它的核心思想是:先从知识库检索相关资料,再把资料作为上下文交给模型生成回答。这样可以减少模型幻觉,并让模型回答项目文档、课程资料、企业规范等私有知识。
RAG 基本流程:
| 文档上传 ↓ 文本切分 ↓ 生成向量 ↓ 存入向量数据库(pgvector) ↓ 用户提问 ↓ 问题向量化 ↓ 相似度检索 ↓ 取出相关片段 ↓ 拼接到 Prompt ↓ 模型生成回答 |
5. 结构化输出:让 AI 结果能被系统继续处理
AI 如果只返回一段自然语言,人能看懂,但系统不好保存、筛选和后续处理。结构化输出可以把模型结果转换成 Java 对象或 JSON,例如学习计划、复习任务、简历建议等。
| { "title": "Java 后端 7 天复习计划", "tasks": [ { "day": 1, "topic": "Java 集合", "content": "复习 HashMap、ArrayList、ConcurrentHashMap" } ] } |
-
记忆:支持多轮对话
普通 HTTP 接口是无状态的,但 Agent 往往需要记住上下文。常见做法是每次请求携带 conversationId,用 Redis 存短期上下文,用 MySQL 存长期消息记录,用向量库沉淀长期知识记忆。
四、项目案例:Java 后端学习助手 Agent
为了让分享更具体,我们设计一个适合实习项目和技术分享会的案例:Java 后端学习助手 Agent。
| 项目定位 | 说明 |
| 目标用户 | 准备 Java 后端实习的同学。 |
| 核心问题 | 不知道怎么复习、项目不会包装、八股不会结合项目讲、面试回答不够具体。 |
| Agent 能力 | 知识问答、面试回答优化、项目亮点包装、学习计划生成、错题查询和任务创建。 |
| 技术亮点 | Spring AI、Tool Calling、RAG、结构化输出、会话记忆、权限控制和日志追踪。 |
核心功能清单
-
Java 后端知识问答
-
面试题回答优化
-
项目亮点包装
-
学习计划生成
-
简历技术点分析
-
查询用户历史错题
-
生成结构化复习任务
-
基于知识库的 RAG 问答
五、系统架构与模块设计
-
普通 CRUD 架构
| 前端 ↓ Controller ↓ Service ↓ Mapper ↓ MySQL |
-
AI Agent 架构
| 前端 ↓ AI Controller ↓ AgentService ↓ Prompt 构建 ↓ ChatClient 调用模型 ↓ Tool Calling / RAG / Memory ↓ 业务系统 / 数据库 / Redis / 向量库 ↓ 统一响应 BaseResponse |
-
推荐目录结构
| src/main/java/com/example/aiagent ├── controller │ └── AiController.java ├── service │ ├── AiAgentService.java │ ├── RagChatService.java │ └── StudyPlanService.java ├── tools │ └── StudyTools.java ├── model │ ├── request │ │ └── AiChatRequest.java │ ├── response │ │ └── AiChatResponse.java │ └── dto │ └── StudyPlanResult.java ├── rag │ ├── DocumentIngestionService.java │ └── VectorStoreService.java ├── common │ ├── BaseResponse.java │ ├── ResultUtils.java │ └── ErrorCode.java └── exception ├── BusinessException.java └── GlobalExceptionHandler.java |
-
技术选型
| 后端技术栈 | 说明 |
| Java / Spring Boot | 承担基础 Web 服务、接口路由、参数校验和依赖注入。 |
| Spring AI | 封装模型调用、工具调用、RAG Advisor、结构化输出等能力。 |
| MyBatis-Plus / MySQL | 保存用户、错题、学习计划、聊天记录等业务数据。 |
| Redis | 保存短期会话上下文、热点数据和限流计数。 |
| VectorStore | 存储文档向量,用于 RAG 检索增强。 |
| Knife4j / Swagger | 生成接口文档,方便前后端联调。 |
| Docker / Nginx | 完成部署、反向代理和静态资源托管。 |
六、核心代码实现示例
1. 统一响应对象
| @Data @AllArgsConstructor @NoArgsConstructor public class BaseResponse<T> { private int code; private String message; private T data; } public class ResultUtils { public static <T> BaseResponse<T> success(T data) { return new BaseResponse<>(0, "ok", data); } public static <T> BaseResponse<T> error(int code, String message) { return new BaseResponse<>(code, message, null); } } |
-
AI 请求与响应对象
| @Data public class AiChatRequest { @NotBlank(message = "问题不能为空") private String message; private String conversationId; } @Data @Builder public class AiChatResponse { private String answer; private Boolean usedTool; private Boolean usedRag; private String conversationId; } |
-
Controller 层
| @RestController @RequestMapping("/ai") @RequiredArgsConstructor public class AiController { private final AiAgentService aiAgentService; @PostMapping("/chat") public BaseResponse<AiChatResponse> chat(@RequestBody @Valid AiChatRequest request) { AiChatResponse response = aiAgentService.chat(request); return ResultUtils.success(response); } } |
-
基础 ChatClient 调用
| @Service @RequiredArgsConstructor public class AiAgentService { private final ChatClient chatClient; public AiChatResponse chat(AiChatRequest request) { String answer = chatClient .prompt() .system(""" 你是一个 Java 后端学习助手。 你擅长 Spring Boot、MySQL、Redis、项目面试和实习求职。 回答时要清晰、具体,尽量结合真实项目场景。 """) .user(request.getMessage()) .call() .content(); return AiChatResponse.builder() .answer(answer) .usedTool(false) .usedRag(false) .conversationId(request.getConversationId()) .build(); } } |
这个版本只是 AI Chat,还不是真正的 Agent。它能回答问题,但不能查数据库、不能调用业务系统,也不能把结果保存到系统中。
-
注册工具调用
| @Service @RequiredArgsConstructor public class AiAgentService { private final ChatClient chatClient; private final StudyTools studyTools; public AiChatResponse chat(AiChatRequest request) { String answer = chatClient .prompt() .system(""" 你是一个 Java 后端学习助手。 当用户需要查询错题、创建学习任务、生成复习计划时, 可以调用系统提供的工具。 不要编造用户数据,必须通过工具查询。 """) .user(request.getMessage()) .tools(studyTools) .call() .content(); return AiChatResponse.builder() .answer(answer) .usedTool(true) .usedRag(false) .conversationId(request.getConversationId()) .build(); } } |
这时用户可以说:“帮我看看最近有哪些 Redis 相关错题,并安排一个复习任务。”Agent 可以先调用错题查询工具,再调用学习任务创建工具,最后整合成回答。
-
RAG 问答服务
| @Service @RequiredArgsConstructor public class RagChatService { private final ChatModel chatModel; private final VectorStore vectorStore; public String askWithRag(String question) { QuestionAnswerAdvisor advisor = QuestionAnswerAdvisor .builder(vectorStore) .build(); return ChatClient.builder(chatModel) .build() .prompt() .system(""" 你是一个 Java 后端项目文档助手。 请优先根据知识库内容回答。 如果知识库中没有相关信息,请明确说明不知道,不要编造。 """) .user(question) .advisors(advisor) .call() .content(); } } |
-
结构化学习计划
| @Data public class StudyPlanResult { private String title; private List<StudyTask> tasks; @Data public static class StudyTask { private Integer day; private String topic; private String content; } } public StudyPlanResult generateStudyPlan(String userInput) { return chatClient .prompt() .system(""" 你是一个 Java 后端学习规划助手。 请根据用户目标生成结构化学习计划。 内容要适合实习面试准备。 """) .user(userInput) .call() .entity(StudyPlanResult.class); } |
结构化输出的价值在于:AI 不只是生成一段话,而是生成后端系统可以继续保存、展示和处理的数据。
-
会话记录表设计
| CREATE TABLE ai_chat_message ( id BIGINT PRIMARY KEY AUTO_INCREMENT, conversation_id VARCHAR(64) NOT NULL, user_id BIGINT NOT NULL, role VARCHAR(20) NOT NULL, content TEXT NOT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); |
七、工程化落地:安全、日志、评估与监控
1. 安全控制
AI Agent 的安全边界一定要放在后端代码里,而不是只依赖 Prompt。模型可以提出工具调用请求,但真正是否执行,必须由后端校验用户权限、参数合法性和操作风险。
| @Tool(description = "删除学习任务,执行前必须确认用户权限") public String deleteStudyTask(Long userId, Long taskId) { if (!permissionService.canDeleteTask(userId, taskId)) { throw new BusinessException(ErrorCode.NO_AUTH_ERROR); } studyPlanService.deleteTask(taskId); return "删除成功"; } |
-
低风险工具:查询资料、生成建议、解释知识点,可以直接执行。
-
中风险工具:创建任务、修改计划,需要参数校验和操作日志。
-
高风险工具:删除数据、发送消息、扣费操作,需要二次确认和权限校验。
2. 日志追踪
AI Agent 的排查比普通接口更复杂。除了接口请求日志,还要记录 Prompt、工具调用、RAG 检索结果和模型响应。
| 建议记录字段 | 说明 |
| traceId | 串联一次请求链路。 |
| conversationId | 定位一次多轮对话。 |
| userId | 定位用户和权限边界。 |
| prompt | 排查模型为什么这样回答。 |
| toolName / toolArgs | 排查模型选择了哪个工具、入参是否正确。 |
| toolResult | 排查工具返回是否异常。 |
| retrievedDocs | 排查 RAG 检索是否命中正确文档。 |
| modelResponse | 记录最终模型输出。 |
-
结果评估
普通接口只要状态码和数据正确即可,但 AI 输出还要评估准确性、相关性、稳定性和安全性。可以准备一批固定测试问题,每次改 Prompt、工具或知识库后重新测试。
-
事实是否准确
-
是否基于知识库回答
-
是否出现编造
-
是否错误调用工具
-
是否泄露敏感信息
-
结构化输出能否被正常解析
八、常见踩坑与优化建议
1. 把 AI Agent 理解成简单调用大模型
如果只是把用户问题发给模型,再把文本返回,这只能算 AI Chat。真正的 Agent 要能理解意图、选择工具、检索资料、执行任务,并且能被后端工程体系控制。
2. 工具描述写得太模糊
工具描述越模糊,模型越容易误用。建议描述清楚工具的用途、输入含义、返回内容和使用场景。
| // 不推荐 @Tool(description = "处理任务") public String handleTask(String input) { ... } // 推荐 @Tool(description = "根据用户 ID 查询最近 10 条 Java 后端面试错题") public List<WrongQuestionVO> getRecentJavaWrongQuestions(Long userId) { ... } |
3.RAG 不做边界控制
知识库没有答案时,模型可能会编造。建议在系统 Prompt 中明确要求:如果知识库中没有相关信息,就回答“当前知识库中没有找到相关信息”,不要编造。
4. 忽略结构化输出异常
模型生成 JSON 时可能字段缺失、格式错误或类型不匹配。后端要做解析异常处理、重试机制和兜底返回。
5. 不做用户权限隔离
如果工具能查询用户数据,必须保证只能查询当前登录用户有权限访问的数据。不要相信模型传入的 userId,要以后端登录态为准。
九、如何写进简历与面试表达
简历普通写法
| 使用 Spring Boot 和大模型 API 实现 AI 问答功能。 |
这个写法太普通,看不出工程能力,也容易被面试官认为只是调接口。
简历优化写法
| 基于 Spring Boot + Spring AI 构建 Java 后端学习助手 Agent,实现自然语言问答、工具调用、RAG 知识库检索和结构化学习计划生成;通过 @Tool 封装错题查询、学习任务创建等后端能力,使模型能够根据用户意图自动调用业务工具;使用向量数据库存储项目文档和面试资料,结合 RAG 提升回答准确性;对 AI 请求链路记录 conversationId、toolName、toolArgs 和模型响应,方便问题排查和后续优化。 |
它和普通 ChatGPT 调接口有什么区别?
| 普通调接口主要是把用户问题发给模型,然后返回一段文本。而我的项目更偏 Agent 化,模型可以根据用户意图决定是否调用后端工具。比如用户说“帮我看最近 Redis 错题并安排复习任务”,模型会先调用错题查询工具,再调用学习任务创建工具,最后整合成回答。也就是说,它不只是聊天,而是能结合业务系统完成任务。 |
RAG 是怎么实现的?
| RAG 的流程是先把项目文档、面试资料等内容切分成文本片段,然后通过 Embedding 模型转成向量,存入向量数据库。用户提问时,系统会把问题也转成向量,然后做相似度检索,找出最相关的文档片段。最后把这些片段作为上下文传给大模型,让模型基于检索到的资料回答。这样可以减少模型胡编,也能回答一些模型原本不知道的项目内部知识。 |
工具调用有什么安全风险?
| 工具调用的风险主要是模型可能错误选择工具,或者用户通过提示词诱导模型执行敏感操作。所以我不会让模型直接操作数据库,而是把工具封装成受控的 Java 方法。每个工具内部都要做参数校验、权限校验和日志记录。对于删除、修改这类高风险操作,还可以增加二次确认。模型只负责提出调用请求,真正是否执行由后端业务代码控制。 |
参考的学习资料
入门的话可以先做黑马的rag项目(spring ai)
1.可以从GitHub上拉取一些优秀的项目,结合ai去阅读和学习
比如这些链接
https://github.com/datawhalechina/hello-agents?tab=readme-ov-file和文档
https://github.com/jjyaoao/helloagents
2.可以去知识星球上跟着一些大佬去做ai agent项目
3.阅读官方文档比如spring ai等等,学习官方的设计思想
4.学有余力的同学可以去学学LangChain和LangChain4j
更多推荐



所有评论(0)