Java 对接大模型,5 个开箱即用的工具类,复制直接省半天时间

0 阅读5分钟

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 落地实操补全合集」