SpringAI RAG MCP Agent,AI 智能体企业级实战(25年必学 - 3 - AI 应用开发 笔记
已实现 敏感词替换 Advisor,此时效果见图片,代码见末尾

▼java复制代码@Slf4j public class ProhibitedWordCheckAdvisor implements CallAroundAdvisor, StreamAroundAdvisor { @Resource private SensitiveWordHelper sensitiveWordHelper; @Override public String getName() { return this.getClass().getSimpleName(); } @Override public int getOrder() { return 0; } private AdvisedRequest before(AdvisedRequest request) { String userText = request.userText(); boolean hasSensitive = SensitiveWordHelper.contains(userText); if (hasSensitive) { List<String> sensitiveWords = SensitiveWordHelper.findAll(userText); // 1. 对每个敏感词单独脱敏,再组成新列表 List<String> maskedSensitiveWords = sensitiveWords.stream() .map(this::maskText) // 调用之前的maskText方法,每个词单独脱敏 .collect(Collectors.toList()); // 2. 打印脱敏后的敏感词列表 log.warn("Content contains {} sensitive words, will be replaced. Sensitive words (masked): {}", sensitiveWords.size(), // 第一个{}:敏感词总数 maskedSensitiveWords); // 第二个{}:脱敏后的敏感词列表 // 3. 替换敏感词并二次验证 - 直接替换成“*” userText = SensitiveWordHelper.replace(userText); if (sensitiveWordHelper.contains(userText)) { userText = SensitiveWordHelper.replace(userText, '*'); log.error("Sensitive words not completely replaced! "); // 日志首尾脱敏 } } // 仅在文本有修改时才创建新请求(优化性能) if (!userText.equals(request.userText())) { return AdvisedRequest.from(request) .userText(userText) .build(); } return request; // 文本未修改时返回原始请求 } // 辅助方法:对敏感词进行脱敏处理 // 两个字:显示第一个字,第二个字用*代替 // 大于两个字:保留首尾两个字,中间用*代替 private String maskText(String text) { // 空字符串直接返回 if (text == null || text.isEmpty()) { return text; } int length = text.length(); if (length <= 1) { return "*"; } // 处理两个字的情况:只保留第一个字 if (length == 2) { return text.charAt(0) + "*"; } // 处理大于两个字的情况:保留首尾,中间用*代替 return text.charAt(0) + "*".repeat(length - 2) + text.charAt(length - 1); } @Override public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) { return chain.nextAroundCall(this.before(advisedRequest)); } @Override public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) { return chain.nextAroundStream(this.before(advisedRequest)); } }
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
内容推荐
AI 超级智能体 - 基于mysql的消息存储
4
SpringAl+RAG+MCP全栈|AI超级智能体企业级实战项目中:stdio连接方式调用MCP服务问题运行测试时解决:1. 先查看MCP server那的yml文件,文件名有没有写错2. 修改server端的"application-stdio.yml",把每一个报错发给deepseek再验证之后,得出结论:Server 的 stdout 完全被污染了:Spring Boot Banner 完
3
SpringAI + RAG + MCP 全栈 | AI 超级智能体企业级实战(26年必学) - 第三期:基础内容 笔记
3
AI超级智能体项目_踩坑记录_PGVector维度冲突
2
Code Log-AI超级智能体项目,开发日志。SpringAI + RAG + MCP 全栈 | AI 超级智能体企业级实战(26年必学)
2
作者分享
有没有人记得鱼皮之前分享过一个Skill,可以让模型自己去看框架的官方文档,根据文档写代码……我找不到这个Skill,有人可以分享一下不~
1
求助:MCP - 使用过sse传递环境变量,显示无法调用搜图。但 stdio模式下已验证可行……
```java
package com.lzxx.lzxximagesearchmcpserver.tools;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class ImageSearchTool {
// 替换为你的 Pexels API 密钥(需从官网申请)
private static final String API_KEY = "dsd";
// Pexels 常规搜索接口(请以文档为准)
private static final String API_URL = "https://api.pexels.com/v1/search";
// 从环境变量读取图片数量限制,默认返回5张
private static final int DEFAULT_LIMIT = 5;
// Pexels API 最大支持80张/页
private static final int MAX_LIMIT = 80;
@Tool(description = "search image from web, return specified number of images controlled by environment variable IMAGE_SEARCH_LIMIT")
public String searchImage(@ToolParam(description = "Search query keyword") String query) {
try {
int finalLimit = determineFinalLimit();
return String.join(",", searchMediumImages(query, finalLimit));
} catch (Exception e) {
return "Error search image: " + e.getMessage();
}
}
// 确定最终使用的数量(优先级处理)
private int determineFinalLimit() {
// 1. 读取环境变量(区分大小写,Linux/macOS 环境变量通常为大写)
String limitStr = System.getenv("IMAGE_SEARCH_LIMIT");
int limit = Integer.parseInt(limitStr);
// 2. 完整的校验逻辑
if (StrUtil.isBlank(limitStr)) {
limit = DEFAULT_LIMIT;
} else if (!limitStr.matches("\\d+")) {
limit = DEFAULT_LIMIT;
} else if (limit <= 0 || limit > MAX_LIMIT) {
limit = DEFAULT_LIMIT;
}
return limit;
}
/**
* 搜索中等尺寸的图片列表
*
* @param query
* @return
*/
public List<String> searchMediumImages(String query, int limit) {
// 设置请求头(包含API密钥)
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", API_KEY);
// 设置请求参数(仅包含query,可根据文档补充page、per_page等参数)
Map<String, Object> params = new HashMap<>();
params.put("query", query);
params.put("per_page", limit); // 添加数量控制参数:从环境变量读取的限制值
// 发送 GET 请求
String response = HttpUtil.createGet(API_URL)
.addHeaders(headers)
.form(params)
.execute()
.body();
// 解析响应JSON(假设响应结构包含"photos"数组,每个元素包含"medium"字段)
return JSONUtil.parseObj(response)
.getJSONArray("photos")
.stream()
.map(photoObj -> (JSONObject) photoObj)
.map(photoObj -> photoObj.getJSONObject("src"))
.map(photo -> photo.getStr("medium"))
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
}
}
```
```json
{
"mcpServers": {
" lzxx-image-search-mcp-server": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dspring.main.web-application-type=none",
"-Dlogging.pattern.console=",
"-jar",
"lzxx-image-search-mcp-server/target/lzxx-image-search-mcp-server-0.0.1-SNAPSHOT.jar"
],
"env": {"IMAGE_SEARCH_LIMIT": "3"}
}
}
}
```
1
超级智能体项目的 AI大模型接入 模块,如何使用 SpringAI框架 API 方式接入 doubao大模型?
豆包大模型是支持openAI协议的,所以我按照文档使用了 类open AI的方式接入,但一直无法编译通过。
(附报错图、yml图、代码图)
麻烦解决的朋友给我评论留言,感谢!(ps sdk和http方式不会的可以找我,那两种方式都成功接入了大模型)
2
项目
求一个 go版本 的oj项目。最近刚刚过了一遍语法,想看看项目中的go是咋用的
4
项目 关于【sdk上传maven中央仓库】的提问
我根据b站某球友的视频和博客顺利完成了前期的所有准备,包括:注册jira与提一个new project;弄一个gpg密钥;修改setting;修改pom。步骤与修改的细节我都检查了好几次,确认没问题(跟博客几乎一样,除了基本信息),但是就是无法部署工程,说没权限啥的。
希望解决过的朋友q我一下,如果能远程帮我看看的话,感激不尽了[抱拳][抱拳][抱拳]弄了好久,很崩溃的说[流泪][流泪][流泪]
6

