程序调用 AI 大模型 – Java
1、SDK 接入
安装阿里云百炼SDK_大模型服务平台百炼(Model Studio)-阿里云帮助中心
<dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><!-- 请将 'the-latest-version' 替换为最新版本号:https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --><version>the-latest-version</version>
</dependency>
// 建议dashscope SDK的版本 >= 2.12.0
import java.util.Arrays;
import java.lang.System;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;public class Main {public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {Generation gen = new Generation();Message systemMsg = Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();Message userMsg = Message.builder().role(Role.USER.getValue()).content("你是谁?").build();GenerationParam param = GenerationParam.builder()// 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx").apiKey(System.getenv("DASHSCOPE_API_KEY"))// 此处以qwen-plus为例,可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models.model("qwen-plus").messages(Arrays.asList(systemMsg, userMsg)).resultFormat(GenerationParam.ResultFormat.MESSAGE).build();return gen.call(param);}public static void main(String[] args) {try {GenerationResult result = callWithMessage();System.out.println(JsonUtils.toJson(result));} catch (ApiException | NoApiKeyException | InputRequiredException e) {// 使用日志框架记录异常信息System.err.println("An error occurred while calling the generation service: " + e.getMessage());}System.exit(0);}
}
2、HTTP 接入
对于 SDK 不支持的编程语言或需要更灵活控制的场景,可以直接使用 HTTP 请求调用 AI 大模型的 API。
使用建议:优先使用 SDK ,不支持 SDK ,再考虑 HTTP 调用
curl --location "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation" \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header "Content-Type: application/json" \
--data '{"model": "qwen-plus","input":{"messages":[ {"role": "system","content": "You are a helpful assistant."},{"role": "user","content": "你是谁?"}]},"parameters": {"result_format": "message"}
}'
转换为使用Hutool工具类的Java代码
package com.ping.aiagent.demo.invoke;import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ping.aiagent.contant.TestAPI;/*** HTTP 方式调用 AI*/
public class DashscopeRequest {public static void main(String[] args) {// API密钥String apiKey = TestAPI.API_KEY;// 构建请求URLString url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";// 构建请求JSON体JSONObject requestBody = new JSONObject();requestBody.set("model", "qwen-plus");JSONObject input = new JSONObject();// 创建消息数组JSONArray messages = new JSONArray();// 添加系统消息messages.add(new JSONObject().set("role", "system").set("content", "You are a helpful assistant."));// 添加用户消息messages.add(new JSONObject().set("role", "user").set("content", "你是谁?"));input.set("messages", messages);JSONObject parameters = new JSONObject();parameters.set("result_format", "message");requestBody.set("input", input);requestBody.set("parameters", parameters);// 发送POST请求String response = HttpRequest.post(url).header("Authorization", "Bearer " + apiKey).header("Content-Type", "application/json").body(requestBody.toString()).timeout(20000).execute().body();System.out.println(response);}
}
3、Spring AI
Spring AI 是 Spring 生态系统的新成员,旨在简化 AI 功能与 Spring 应用的集成。Spring AI 官方文档
Spring AI 默认没有支持所有的大模型(尤其是国产的)。
Spring AI AlibabaSpring AI Alibaba 官网_快速构建 JAVA AI 应用
阿里对 Spring AI 做了一个兼容和升级,可以更好的和阿里系的大模型兼容。
<dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M5.1</version>
</dependency><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories>
更改配置文件
spring:application:name: ping-ai-agentai:dashscope:api-key: < API KEY >chat:options:model: qwq-plus
package com.ping.aiagent.demo.invoke;import jakarta.annotation.Resource;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;/*** Spring AI 模型框架调用 AI 大模型*/
@Component
public class SpringAiAiInvoke implements CommandLineRunner {@Resourceprivate ChatModel dashscopeChatModel; // 先通过名称 找不到再通过类型 一定要是这个名称// 还可以通过 ChatClient 对话客户端的方式去调用 能够提供更多的高级 AI 交互功能@Overridepublic void run(String... args) throws Exception {AssistantMessage assistantMessage = dashscopeChatModel.call(new Prompt("你好呀")).getResult().getOutput(); // 取出 getResult 对象的内容System.out.println(assistantMessage.getText()); // 拿到文本响应}
}
4、LangChain4j
知名 AI 框架 LangChain 的 Java 版本。
LangChain 官方是没有支持阿里系大模型的,只能用社区版本整合的大模型包。LangChain4j模型集成。
接入阿里云灵积模型,参考官方文档:DashScope 模型集成。
<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-dashscope</artifactId><version>1.0.0-beta2</version>
</dependency>
本地部署和接入 AI 大模型
1、本地安装大模型。
官网安装
无需自己执行脚本安装,也省去了复杂的环境配置。
Ollama 不仅提供了友好的命令行界面,还支持 API 调用,方便与各种应用程序集成。参考:官方 API 文档。
检测模型是否运行:localhost:11434。
2、Spring AI 调用 Ollama 大模型
Spring AI 原生支持调用 Ollama 大模型,直接参考 [官方文档](Ollama-阿里云Spring AI Alibaba官网官网) 编写配置和代码即可。
配置依赖。
<!-- https://java2ai.com/docs/1.0.0-M6.1/models/ollama/ -->
<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId><version>1.0.0-M6</version>
</dependency><!-- 需要引入仓库配置,才能下载到最新的 Spring AI 的相关依赖 -->
<repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository>
</repositories>
调用配置
spring:ai:ollama:base-url: http://localhost:11434chat:model: llama3
扩展:火山引擎
火山方舟管理控制台
1、HTTP 接入
curl https://ark.cn-beijing.volces.com/api/v3/chat/completions \-H "Content-Type: application/json" \-H "Authorization: Bearer <Your Api Key>" \-d $'{"model": "doubao-seed-1-6-250615","messages": [{"content": [{"image_url": {"url": "https://ark-project.tos-cn-beijing.ivolces.com/images/view.jpeg"},"type": "image_url"},{"text": "图片主要讲了什么?","type": "text"}],"role": "user"}]
}'
转换为使用Hutool工具类的Java代码
package com.ping.aiagent.demo.invoke;import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ping.aiagent.contant.TestAPI;public class VolcengineImageChat {public static void main(String[] args) {String url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";String token = TestAPI.VolcengineImageChat_Api_KET;if (token == null || token.trim().isEmpty()) {throw new IllegalArgumentException("API密钥不能为空");}String imageUrl = "https://cdn.jsdmirror.com/gh/qiuping01/my-images/202508191817326.jpg";try {int statusCode = HttpRequest.get(imageUrl).timeout(10000).execute().getStatus();if (statusCode != 200) {System.err.println("警告: 图片URL可能无法访问,状态码: " + statusCode);}} catch (Exception e) {System.err.println("警告: 无法验证图片URL: " + e.getMessage());}JSONObject requestBody = new JSONObject();requestBody.set("model", "doubao-seed-1-6-250615");JSONArray messages = new JSONArray();JSONArray contentArray = new JSONArray();JSONObject imageObject = new JSONObject();imageObject.set("type", "image_url");JSONObject imageUrlObject = new JSONObject();imageUrlObject.set("url", imageUrl);imageObject.set("image_url", imageUrlObject);contentArray.add(imageObject);JSONObject textObject = new JSONObject();textObject.set("type", "text");textObject.set("text", "图片主要讲了什么?");contentArray.add(textObject);JSONObject userMessage = new JSONObject();userMessage.set("role", "user");userMessage.set("content", contentArray);messages.add(userMessage);requestBody.set("messages", messages);int maxRetries = 3;int retryCount = 0;String response = null;while (retryCount < maxRetries) {try {System.out.println("发送请求到: " + url);long startMs = System.currentTimeMillis();response = HttpRequest.post(url).header("Content-Type", "application/json").header("Authorization", "Bearer " + token).body(requestBody.toString()).timeout(120000).execute().body();long costMs = System.currentTimeMillis() - startMs;// 直观输出printPrettyResponse(response, imageUrl, "图片主要讲了什么?", costMs);break;} catch (Exception e) {retryCount++;System.err.println("请求失败,第 " + retryCount + " 次重试...");System.err.println("错误信息: " + e.getMessage());if (retryCount >= maxRetries) {System.err.println("已达到最大重试次数,放弃请求");throw new RuntimeException("请求失败,已达到最大重试次数", e);}try {Thread.sleep(2000L * retryCount);} catch (InterruptedException ie) {Thread.currentThread().interrupt();throw new RuntimeException("重试等待被中断", ie);}}}}private static void printPrettyResponse(String response, String imageUrl, String userQuestion, long costMs) {if (response == null || response.isEmpty()) {System.out.println("未收到响应");return;}JSONObject resp;try {resp = JSONUtil.parseObj(response);} catch (Exception e) {System.out.println("收到非JSON响应,原始内容:\n" + response);return;}// 错误处理if (resp.containsKey("error")) {JSONObject error = resp.getJSONObject("error");System.out.println("\n================== 豆包 AI 响应(错误) ==================");System.out.println("错误代码: " + error.getStr("code", "-"));System.out.println("错误信息: " + error.getStr("message", "-"));System.out.println("原始响应(JSON):\n" + JSONUtil.toJsonPrettyStr(resp));System.out.println("========================================================");return;}String id = resp.getStr("id", "-");String model = resp.getStr("model", "-");JSONObject usage = resp.getJSONObject("usage");Integer promptTokens = usage.getInt("prompt_tokens", null);Integer completionTokens = usage.getInt("completion_tokens", null);Integer totalTokens = usage.getInt("total_tokens", null);// 提取助手回答(兼容字符串或分段数组)String assistantAnswer = extractAssistantAnswer(resp);System.out.println("\n================== 豆包 AI 响应(已格式化) ===============");System.out.println("请求信息");System.out.println("- 图片URL : " + imageUrl);System.out.println("- 用户问题 : " + userQuestion);System.out.println("- 耗时 : " + costMs + " ms");System.out.println("\n元信息");System.out.println("- 请求ID : " + id);System.out.println("- 模型 : " + model);if (promptTokens != null || completionTokens != null || totalTokens != null) {System.out.println("- Token用量 : prompt=" + safeInt(promptTokens)+ ", completion=" + safeInt(completionTokens)+ ", total=" + safeInt(totalTokens));}System.out.println("\n助手回答");System.out.println(assistantAnswer == null || assistantAnswer.isEmpty() ? "(空)" : assistantAnswer);System.out.println("\n原始响应(JSON)"); // 便于排查System.out.println(JSONUtil.toJsonPrettyStr(resp));System.out.println("========================================================\n");}private static String extractAssistantAnswer(JSONObject resp) {try {JSONArray choices = resp.getJSONArray("choices");if (choices == null || choices.isEmpty()) {return "";}JSONObject first = choices.getJSONObject(0);if (first == null) return "";JSONObject message = first.getJSONObject("message");if (message == null) return "";Object content = message.get("content");if (content == null) return "";// 可能是字符串if (content instanceof CharSequence) {return String.valueOf(content).trim();}// 也可能是数组(多模态分段)if (content instanceof JSONArray) {JSONArray parts = (JSONArray) content;StringBuilder builder = new StringBuilder();for (int i = 0; i < parts.size(); i++) {JSONObject part = parts.getJSONObject(i);String type = part.getStr("type", "");if ("text".equalsIgnoreCase(type)) {builder.append(part.getStr("text", ""));} else if ("image_url".equalsIgnoreCase(type)) {JSONObject img = part.getJSONObject("image_url");String url = img == null ? "" : img.getStr("url", "");builder.append("\n[图片] ").append(url);}}return builder.toString().trim();}return String.valueOf(content).trim();} catch (Exception e) {return "";}}private static String safeInt(Integer v) {return v == null ? "-" : String.valueOf(v);}
}
2、SDK 调用
<dependency><groupId>com.volcengine</groupId><artifactId>volcengine-java-sdk-ark-runtime</artifactId><version>LATEST</version>
</dependency>
package com.volcengine.ark.runtime;import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionContentPart;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;// 请确保您已将 API Key 存储在环境变量 ARK_API_KEY 中
// 初始化Ark客户端,从环境变量中读取您的API Key
public class ChatCompletionsVisionExample {// 从环境变量中获取您的 API Key。此为默认方式,您可根据需要进行修改static String apiKey = System.getenv("ARK_API_KEY");// 此为默认路径,您可根据业务所在地域进行配置static String baseUrl = "https://ark.cn-beijing.volces.com/api/v3";static ConnectionPool connectionPool = new ConnectionPool(5, 1, TimeUnit.SECONDS);static Dispatcher dispatcher = new Dispatcher();static ArkService service = ArkService.builder().dispatcher(dispatcher).connectionPool(connectionPool).baseUrl(baseUrl).apiKey(apiKey).build();public static void main(String[] args) {System.out.println("----- image input -----");final List<ChatMessage> messages = new ArrayList<>();final List<ChatCompletionContentPart> multiParts = new ArrayList<>();multiParts.add(ChatCompletionContentPart.builder().type("image_url").imageUrl(new ChatCompletionContentPart.ChatCompletionContentPartImageURL("https://ark-project.tos-cn-beijing.ivolces.com/images/view.jpeg")).build());multiParts.add(ChatCompletionContentPart.builder().type("text").text("这是哪里?").build());final ChatMessage userMessage = ChatMessage.builder().role(ChatMessageRole.USER).multiContent(multiParts).build();messages.add(userMessage);ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()// 指定您创建的方舟推理接入点 ID,此处已帮您修改为您的推理接入点 ID.model("doubao-seed-1-6-250615").messages(messages).build();service.createChatCompletion(chatCompletionRequest).getChoices().forEach(choice -> System.out.println(choice.getMessage().getContent()));service.shutdownExecutor();}
}