程序接入大模型几种方式
本文演示了初步使用Spring AI框架接入大模型的几种方式
程序接入大模型
调用方式
可以通过编程的方式在自己的项目中调用AI大模型,又可以分为2种方式:
- 直接调用Al大模型,比如调用DeepSeek(更原生)
对于第1种方式,可以使用特定平台提供的SDK或API,参考平台的文档来接入;也可以使用AI开发框架,比如Spring Al、Spring Al Alibaba、LangChain4j等自主选择大模型进行调用,可以灵活切换使用的大模型而几乎不用修改代码。
- 调用AI大模型平台创建的应用或智能体(更方便)
对于第2种方式,一般只能使用特定平台提供的SDK或API,参考平台的文档来接入,每个大模型服务平台的代码都不一样。
上次在文章Ai初探索——通过阿里云百炼低代码体验来理解AI智能体创建相关知识创建了AI旅游向导,而我们可以通过代码调用我们创建的AI旅游向导。
这个时候就有疑问了,既然我第二种可以不通过代码实现很方便,而且底层都是调用同一个大模型,那为什么我们还要通过代码实现?
实际上在平台上给出的参数是有限值的,你只可以修改平台给出的参数,但是如果想创建更有特色更个性化的AI智能体,还需要使用更多参数去设定。
具体调用参考文档链接地址如下:
大模型服务平台文档
接下来我们都是使用第一种方式来介入AI大模型
SKD接入AI大模型
依赖引入
- JDK版本
Java 21
- Lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<optional>true</optional>
</dependency>
- Hutool工具库
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.37</version>
</dependency>
- Knife4j接口文档
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
- SDK引入——DashScope
<!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>2.19.1</version>
</dependency>
配置引入
spring:
application:
name: ai-agent
server:
port: 8123
servlet:
context-path: /api
# springdoc-openapi
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: 'default'
paths-to-match: '/**'
packages-to-scan: {controller层的全包类路径}
# knife4j
knife4j:
enable: true
setting:
language: zh_cn
申请一个Api Key
实现代码
首先可以看一下这个文档模型理解文档
public class SdkAiInvoke {
@Resource
private ApiKeyConfig apiKeyConfig;
public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {
/*
创建了一个 Generation 类的实例 gen。
Generation 类是阿里云 DashScope SDK 中用于与模型进行交互并生成响应的关键类 。
就类似于一个 AI 代理,它负责与模型进行交互,接收用户的输入,生成响应,并将响应返回给用户。
*/
Generation gen = new Generation();
/*
这是一个系统消息,它告诉 AI 代理你是一个系统,你将扮演一个 AI 旅游向导的角色。
使用了构造器模式来构造消息
*/
Message systemMsg = Message.builder()
.role(Role.SYSTEM.getValue())
.content("你是一位备受欢迎且经验丰富的AI旅游向导,名为悦游。你对全球各地的旅游景点、美食、住宿、交通及当地文化习俗了如指掌。你擅长根据不同游客的兴趣爱好、预算、时间安排,量身定制个性化的旅游攻略。回答简洁明了、生动有趣,确保信息准确且实用。当游客提问模糊时,友好地通过询问关键信息来明确需求,如想去的地区、旅行时长、预算范围等。始终保持热情积极的态度,致力于为游客打造难忘的旅行体验。")
.build();
/**
* 这是一个用户消息,它告诉 AI 代理你是一个用户,你将扮演一个游客的角色。
* 你将向 AI 旅游向导询问关于旅游攻略的问题。
*/
Message userMsg = Message.builder()
.role(Role.USER.getValue())
.content("你好,我是Star,我现在正在学习AI智能体编程项目")
.build();
/**
* 这是一个 GenerationParam 对象,它包含了调用模型所需的参数。
* 例如,apiKey 是你的 API Key,model 是你选择的模型名称
* messages 是你发送给 AI 代理的消息列表
* resultFormat 是你希望模型返回的结果格式,这里是 MESSAGE。
*/
GenerationParam param = GenerationParam.builder()
// 若没有配置环境变量,请用百炼API Key将下行替换为:.apiKey("sk-xxx")
.apiKey(ApiKeyConfig.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); //它提供了调用模型的方法,例如代码中的 call 方法:
}
public static void main(String[] args) {
try {
/**
* 调用 callWithMessage 方法,该方法会调用模型并返回结果。
* 也就是上面我们传入了两个消息,一个是系统消息,一个是用户消息
* 返回出来的消息,我们得到的信息就是助手消息
*/
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);
}
}
查看源码发现ResultFormat的格式有以下两种:
运行main函数后得到结果如下:
这个时候我们就已经初步使用SDK接入的方式搭建了一个AI旅游向导的智能体,但是我们只能和它进行一次对话,它也只能给我们一次响应。
HTTP接入
Http接入文档
注意我们是使用的DashScope兼容,而不是OpenAI兼容
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": "你是一个AI旅游向导"
},
{
"role": "user",
"content": "你好,我是Star"
}
]
},
"parameters": {
"result_format": "message"
}
}'
然后用AI工具,将代码转换成Java里面发送Http请求的格式。
public class HttpAiInvoke {
public static void main(String[] args) {
String apiKey = ApiKeyConfig.api_key;
String url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation";
// 构建请求体
JSONObject requestBody = new JSONObject();
requestBody.set("model", "qwen-plus");
JSONObject input = new JSONObject();
JSONArray messages = new JSONArray();
JSONObject systemMsg = new JSONObject();
systemMsg.set("role", "system");
systemMsg.set("content", "你是一个AI旅游向导");
messages.add(systemMsg);
JSONObject userMsg = new JSONObject();
userMsg.set("role", "user");
userMsg.set("content", "你好,我是Star");
messages.add(userMsg);
input.set("messages", messages);
requestBody.set("input", input);
JSONObject parameters = new JSONObject();
parameters.set("result_format", "message");
requestBody.set("parameters", parameters);
// 发送请求
HttpResponse response = HttpRequest.post(url)
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.timeout(20000)
.execute();
System.out.println("Response Code: " + response.getStatus());
System.out.println("Response Body: " + response.body());
}
}
SpringAI接入
依赖
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
<version>1.0.0-M5.1</version>
</dependency>
配置
记得把api-key换成自己的!
代码
@Component
public class SpringAiAiInvoke implements CommandLineRunner {
@Resource
private ChatModel dashscopeChatModel;
@Override
public void run(String... args) throws Exception {
AssistantMessage output = dashscopeChatModel.call(new Prompt("你好,我Star"))
.getResult()
.getOutput();
System.out.println(output.getText());
}
}
CommandLineRunner
CommandLineRunner是 Spring Boot 框架中的一个接口,它提供了一种在 Spring Boot 应用启动完成后立即执行自定义代码的机制。
@FunctionalInterface
public interface CommandLineRunner {
void run(String... args) throws Exception;
}
@FunctionalInterface 是Java 8 引入的一个注解,用于标识一个接口为函数式接口 。
使用CommandLineRunner接口,可以在应用程序启动后执行一些必要的初始化操作,例如加载配置文件、初始化数据库连接、创建默认数据等。
ChatModel
ChatModel 是 Spring AI 框架中用于处理与大型语言模型(LLM)(什么是LLM?)对话的核心接口。它充当了你的应用程序和背后强大 AI 模型(通义千问)之间的“桥梁”或“翻译官”。
简单来说,当调用 dashscopeChatModel.call(…) 时,ChatModel 接手了所有复杂的工作:它将你的输入(“你好,我是Star”)和系统配置,封装成后端模型能理解的格式并发起请求,最后再将模型的响应解析成标准化的** ChatResponse 对象**返回给你.
ChatModel
是 Spring AI 框架中用于处理与大型语言模型(LLM)对话的核心接口。它充当了你的应用程序和背后强大 AI 模型(如你代码中使用的阿里云通义千问)之间的“桥梁”或“翻译官”。
简单来说,当你调用 dashscopeChatModel.call(...)
时,ChatModel
接手了所有复杂的工作:它将你的输入(“你好,我是Star”)和系统配置,封装成后端模型能理解的格式并发起请求,最后再将模型的响应解析成标准化的 ChatResponse
对象返回给你。
💡 核心概念
下面的表格清晰地展示了 ChatModel
的关键组件是如何在代码中体现
组件概念 | 说明 | 在代码中的体现 |
---|---|---|
ChatModel 接口 |
定义调用AI模型的统一方法,最主要的就是 call(Prompt prompt) 方法。 |
dashscopeChatModel.call(new Prompt(...)) |
Prompt 类 |
封装了本次请求的所有信息,包括用户输入(消息)和可选参数。 | new Prompt("你好,我是Star") |
ChatResponse 类 |
封装了AI模型的整个响应,包含结果和元数据(如token消耗、请求ID等)。 | dashscopeChatModel.call(...) 的返回值。 |
Generation 与 AssistantMessage |
ChatResponse 中包含一个或多个 Generation 结果,每个结果的核心输出就是一个 AssistantMessage (助手消息)。 |
getResult().getOutput() 获取到的正是AI模型返回的 AssistantMessage 。 |
🚀 主要优势
- 简化集成:你无需关心如何直接调用阿里云DashScope的HTTP API,
ChatModel
已经做好了底层适配。 - 统一抽象:如果你的项目后期需要切换AI模型(例如从通义千问换到OpenAI的GPT),理论上只需修改配置而无需变动业务代码,因为所有模型都通过统一的
ChatModel
接口进行操作。 - 易于使用:通过依赖注入(
@Resource
)获取Bean,然后简单调用call
方法即可完成交互,非常符合Spring开发者的习惯。
此时我们通过CommandLineRunner实现了当Springboot启动的时候,会调用我们的SpringAiAiInvoke类,从而完成一次交互。
LangChain4j接入
依赖
<!-- https://mvnrepository.com/artifact/dev.langchain4j/langchain4j-community-dashscope -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-dashscope</artifactId>
<version>1.0.0-beta2</version>
</dependency>
代码
public class LangChainAiInvoke {
public static void main(String[] args) {
ChatLanguageModel qwenModel = QwenChatModel.builder()
.apiKey(ApiKeyConfig.api_key)
.modelName("qwen-max")
.build();
String answer = qwenModel.chat("你好,我是Star");
System.out.println(answer);
}
}
运行结果如下:
更多推荐
所有评论(0)