第三节 人工智能服务 AIService

亮子 | 2026-03-26 11:43:05 | 60 | 0 | 0 | 0

三、人工智能服务 AIService

1、什么是AIService

AIService使用面向接口和动态代理的方式完成程序的编写,更灵活的实现高级功能。

1.1、链 Chain(旧版)

链的概念源自 Python 中的 LangChain。其理念是针对每个常见的用例都设置一条链,比如聊天机器人、检索增强生成(RAG)等。链将多个底层组件组合起来,并协调它们之间的交互。链存在的主要问题是不灵活,我们不进行深入的研究。

1.2、人工智能服务 AIService

在LangChain4j中我们使用AIService完成复杂操作。底层组件将由AIService进行组装。

AIService可处理最常见的操作:

  • 为大语言模型格式化输入内容
  • 解析大语言模型的输出结果

它们还支持更高级的功能:

  • 聊天记忆 Chat memory
  • 工具 Tools
  • 检索增强生成 RAG

2、创建AIService

2.1、引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>server-ai-demo</artifactId>
        <groupId>com.shenma</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>demo-ai-service</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.5.9</spring-boot.version>
        <knife4j.version>4.3.0</knife4j.version>
        <langchain4j.version>1.0.0-beta3</langchain4j.version>
        <mybatis-plus.version>3.5.11</mybatis-plus.version>
    </properties>

    <dependencies>
        <!-- web应用程序核心依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 编写和运行测试用例 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 前后端分离中的后端接口测试工具 -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>${knife4j.version}</version>
        </dependency>

        <!-- 引入langchain4j依赖 -->
<!--        <dependency>-->
<!--            <groupId>dev.langchain4j</groupId>-->
<!--            <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>-->
<!--        </dependency>-->

        <!--langchain4j高级功能-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-spring-boot-starter</artifactId>
        </dependency>

        <!-- 接入阿里云百炼平台 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!--引入SpringBoot依赖管理清单-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--引入langchain4j依赖管理清单-->
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-bom</artifactId>
                <version>${langchain4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--引入百炼依赖管理清单-->
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-community-bom</artifactId>
                <version>${langchain4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

2.4、配置文件application.properties

spring.application.name=demo-ai-service
server.port=8084

#阿里百炼平台
langchain4j.community.dashscope.chat-model.api-key=${DASH_SCOPE_API_KEY}
langchain4j.community.dashscope.chat-model.model-name=qwen-max

2.3、创建接口

package com.shenma.ai;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2026/3/26 15:26
 */

public interface Assistant {
    String chat(String userMessage);
}

2.4、测试用例

package com.shenma;

import com.shenma.ai.Assistant;
import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.service.AiServices;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2026/3/26 15:27
 */

@SpringBootTest
public class AIServiceTest {
    @Autowired
    private QwenChatModel qwenChatModel;

    @Test
    public void testChat() {
        //创建AIService
        Assistant assistant = AiServices.create(Assistant.class, qwenChatModel);
        //调用service的接口
        String answer = assistant.chat("你是谁?");
        System.out.println(answer);
    }
}
  • 测试效果

image.png

2.5、@AiService

也可以在Assistant接口上添加@AiService注解

package com.shenma.ai;

import dev.langchain4j.service.spring.AiService;

import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2026/3/26 15:39
 */

//因为我们在配置文件中同时配置了多个大语言模型,所以需要在这里明确指定(EXPLICIT)模型的beanName(qwenChatModel)
//@AiService(wiringMode = AiServiceWiringMode.EXPLICIT,chatModel = "qwenChatModel")
@AiService(wiringMode = EXPLICIT, chatModel = "qwenChatModel")
public interface AiAssistant {
    String chat(String userMessage);
}

测试用例中,我们可以直接注入Assistant对象

package com.shenma;

import com.shenma.ai.AiAssistant;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2026/3/26 15:41
 */

@SpringBootTest
public class TestAiServiceApp {
    @Autowired
    private AiAssistant assistant;

    @Test
    public void testAssistant() {

        String answer = assistant.chat("你是谁?");
        System.out.println(answer);
    }
}

2.6、工作原理

AiServices会**组装Assistant接口以及其他组件**,并使用反射机制创建一个实现Assistant接口的**代理对象**。这个代理对象会处理输入和输出的所有转换工作。在这个例子中,chat方法的输入是一个字符串,但是大模型需要一个UserMessage对象。所以,代理对象将这个字符串转换为UserMessage,并调用聊天语言模型。chat方法的输出类型也是字符串,但是大模型返回的是 AiMessage 对象,代理对象会将其转换为字符串。

简单理解就是:代理对象的作用是输入转换和输出转换