Java 对接大模型,5 个开箱即用的工具类,复制直接省半天
很多同学对接大模型时,重复写 Token 统计、文本清洗、SSE 格式转换这些基础代码,既浪费时间又容易写得不一致。今天把我项目里一直在用的 5 个通用工具类整理出来,全部开箱即用,复制进项目就能直接省半天开发时间。
📦 前置依赖说明
所有工具类兼容 Java 8+、Spring Boot 2.x/3.x,仅需引入两个核心依赖:
<!-- 1. Spring Web 基础依赖(Spring Boot 项目默认自带,SSE工具需要) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.18</version>
</dependency>
<!-- 2. JTokkit Token 计数库(仅Token计数工具需要,轻量无额外依赖) -->
<dependency>
<groupId>me.saro</groupId>
<artifactId>jtokkit</artifactId>
<version>1.0.0</version>
</dependency>
说明:文本清洗、Prompt模板、向量校验三个工具类为纯JDK实现,无需引入任何第三方依赖,直接复制即可使用。若项目已接入LangChain4j,也可直接替换为LangChain4j自带的Token计数能力。
1. Token 计数工具类
精准统计文本 Token 数,用于成本统计、上下文长度校验,避免调用模型时触发长度超限报错。
import me.saro.jwt.util.JTokkit;
/**
* 大模型Token计数工具
* 适配OpenAI/通义千问/文心一言等主流大模型Token计数规则
*/
public class TokenCountUtil {
/**
* 计算文本Token数量
*/
public static int countTokens(String text) {
if (text == null || text.isEmpty()) {
return 0;
}
return JTokkit.countTokens(text);
}
/**
* 判断文本是否超过Token限制
* @param text 待校验文本
* @param maxTokens 最大允许Token数
*/
public static boolean isOverLimit(String text, int maxTokens) {
return countTokens(text) > maxTokens;
}
}
使用示例:
// 统计用户问题Token数
int tokenNum = TokenCountUtil.countTokens("请问年假申请流程是什么?");
// 校验是否超过模型上下文上限
boolean overLimit = TokenCountUtil.isOverLimit(fullContext, 4096);
2. 文本清洗工具类
统一处理文档解析后的乱码、多余空格、换行、无效字符,减少无效 Token 消耗。
/**
* 大模型输入文本清洗工具
* 去除冗余内容,减少无效Token占用
*/
public class TextCleanUtil {
/**
* 通用文本清洗
*/
public static String clean(String content) {
if (content == null) {
return "";
}
// 去除多余空格、制表符,统一为单个空格
content = content.replaceAll("[\\t\\s]+", " ");
// 去除多余换行,保留双换行作为段落分隔
content = content.replaceAll("\\n{3,}", "\n\n");
// 过滤常见无效水印、页眉页脚
content = content.replaceAll("机密|内部资料|第\\d+页共\\d+页", "");
// 去除首尾空白字符
return content.trim();
}
}
使用示例:
// 清洗PDF/Word解析后的原始文本
String cleanContent = TextCleanUtil.clean(rawDocumentText);
3. SSE 格式转换工具类
统一封装 SSE 事件格式,避免每个接口都重复写格式代码,自带心跳保活能力。
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
* SSE流式输出工具
* 统一事件格式,内置心跳保活
*/
public class SseUtil {
/**
* 发送普通文本消息事件
*/
public static void sendEvent(SseEmitter emitter, String content) {
try {
emitter.send(SseEmitter.event()
.name("message")
.data(content));
} catch (Exception e) {
throw new RuntimeException("SSE消息发送失败", e);
}
}
/**
* 发送流式结束事件
*/
public static void sendComplete(SseEmitter emitter) {
try {
emitter.send(SseEmitter.event().name("done").data("[DONE]"));
emitter.complete();
} catch (Exception e) {
emitter.completeWithError(e);
}
}
/**
* 发送心跳保活事件
* 无数据输出时每10秒调用一次,防止网关/nginx断开连接
*/
public static void sendHeartbeat(SseEmitter emitter) {
try {
emitter.send(SseEmitter.event().comment("heartbeat"));
} catch (Exception e) {
emitter.completeWithError(e);
}
}
}
使用示例:
// 控制器中创建SSE对象,设置5分钟超时
SseEmitter emitter = new SseEmitter(300000L);
// 逐段推送大模型返回的分片内容
SseUtil.sendEvent(emitter, chunkContent);
// 全部内容推送完成后结束连接
SseUtil.sendComplete(emitter);
4. Prompt 模板工具类
统一管理提示词模板,避免硬编码在业务代码里,方便迭代优化。
import java.util.HashMap;
import java.util.Map;
/**
* Prompt模板工具
* 统一管理提示词,支持变量填充
*/
public class PromptTemplateUtil {
/**
* RAG问答通用提示词模板(Java 8 兼容写法)
* Java 15+ 可直接使用三引号文本块,写法更简洁
*/
private static final String RAG_ANSWER_TEMPLATE =
"你是企业内部智能客服,请仅基于以下参考文档回答用户问题。\n" +
"如果参考文档中没有答案,请直接回复:暂无相关信息,请联系人工客服。\n\n" +
"参考文档:\n" +
"{context}\n\n" +
"用户问题:\n" +
"{question}";
/**
* 通用模板变量填充
* @param template 模板字符串,变量用{变量名}标记
* @param params 变量键值对
*/
public static String fillTemplate(String template, Map<String, String> params) {
String result = template;
for (Map.Entry<String, String> entry : params.entrySet()) {
result = result.replace("{" + entry.getKey() + "}", entry.getValue());
}
return result;
}
/**
* 快速获取RAG问答提示词
* @param context 检索到的参考文档
* @param question 用户问题
*/
public static String getRagPrompt(String context, String question) {
Map<String, String> params = new HashMap<>(2);
params.put("context", context);
params.put("question", question);
return fillTemplate(RAG_ANSWER_TEMPLATE, params);
}
}
使用示例:
// 一键生成标准化RAG问答Prompt
String finalPrompt = PromptTemplateUtil.getRagPrompt(referenceDoc, userQuestion);
5. 向量维度校验工具类
避免文档入库时向量维度和集合维度不匹配,导致插入 Milvus 等向量库时报错。
/**
* 向量数据校验工具
* 提前拦截无效向量,避免入库报错
*/
public class VectorValidateUtil {
/**
* 校验向量维度是否符合预期
* @param vector 待校验向量
* @param expectDimension 预期维度
*/
public static boolean validateDimension(float[] vector, int expectDimension) {
if (vector == null || vector.length == 0) {
return false;
}
return vector.length == expectDimension;
}
/**
* 校验是否为全0无效向量
*/
public static boolean isZeroVector(float[] vector) {
if (vector == null || vector.length == 0) {
return true;
}
for (float v : vector) {
if (v != 0f) {
return false;
}
}
return true;
}
}
使用示例:
// 向量写入Milvus前做前置校验
if (!VectorValidateUtil.validateDimension(embeddingVector, 1536)) {
throw new BizException("向量维度不匹配,预期1536维");
}
if (VectorValidateUtil.isZeroVector(embeddingVector)) {
throw new BizException("无效向量,无法入库");
}
💡 领取完整资料
关注图片水印内容即Java-AI工程师,打出 【工具包】三个字,即可 有5 个工具类的完整 Java 文件,直接复制进项目即可使用。
📢 明日预告
明天讲 RAG 文档清洗的 3 个实用技巧,解决 PDF 乱码、页眉页脚、表格无效内容的问题,需要的朋友可以先点个关注。
本文属于「Java+AI 落地实操补全合集」