程序接入大模型

调用方式

可以通过编程的方式在自己的项目中调用AI大模型,又可以分为2种方式:

  1. 直接调用Al大模型,比如调用DeepSeek(更原生)

对于第1种方式,可以使用特定平台提供的SDK或API,参考平台的文档来接入;也可以使用AI开发框架,比如Spring Al、Spring Al Alibaba、LangChain4j等自主选择大模型进行调用,可以灵活切换使用的大模型而几乎不用修改代码。

  1. 调用AI大模型平台创建的应用或智能体(更方便)

对于第2种方式,一般只能使用特定平台提供的SDK或API,参考平台的文档来接入,每个大模型服务平台的代码都不一样。

上次在文章Ai初探索——通过阿里云百炼低代码体验来理解AI智能体创建相关知识创建了AI旅游向导,而我们可以通过代码调用我们创建的AI旅游向导。

这个时候就有疑问了,既然我第二种可以不通过代码实现很方便,而且底层都是调用同一个大模型,那为什么我们还要通过代码实现?

实际上在平台上给出的参数是有限值的,你只可以修改平台给出的参数,但是如果想创建更有特色更个性化的AI智能体,还需要使用更多参数去设定。

具体调用参考文档链接地址如下:
大模型服务平台文档

接下来我们都是使用第一种方式来介入AI大模型

SKD接入AI大模型

依赖引入

  1. JDK版本

Java 21

  1. Lombok依赖
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  	<version>1.18.36</version>
    <optional>true</optional>
</dependency>
  1. Hutool工具库
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.37</version>
</dependency>

  1. Knife4j接口文档
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.4.0</version>
</dependency>

  1. 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接入

SpringAI文档

依赖

<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter</artifactId>
    <version>1.0.0-M5.1</version>
</dependency>

配置

yaml文件配置
记得把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 对象**返回给你.

ChatModelSpring 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(...) 的返回值。
GenerationAssistantMessage 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);
    }
}

运行结果如下:
在这里插入图片描述

Logo

更多推荐