AI在线 AI在线

Spring AI这样玩才高级!注解式AI服务开发,这些技巧 GitHub 都找不到

作者:冷冷
2025-03-11 01:23
AI Services是什么AI Services 的设计灵感来源于 Spring Data JPA 和 Retrofit 等框架,采用声明式接口定义所需的 API,然后由框架自动生成实现该接口的代理对象。 这种方法隐藏了与 LLM 交互的复杂性,提供了简单直观的 API。 AI Services 主要处理以下常见操作:格式化输入以发送给 LLM解析 LLM 的输出同时还支持更高级的功能:聊天记忆管理工具调用(Function Calling)检索增强生成(RAG)基本使用示例LangChain4j是 Java 生态系统中的一个流行框架,它提供了两种抽象级别:低级 API 和高级 API。

AI Services是什么

AI Services 的设计灵感来源于 Spring Data JPA 和 Retrofit 等框架,采用声明式接口定义所需的 API,然后由框架自动生成实现该接口的代理对象。这种方法隐藏了与 LLM 交互的复杂性,提供了简单直观的 API。

AI Services 主要处理以下常见操作:

  • 格式化输入以发送给 LLM
  • 解析 LLM 的输出

同时还支持更高级的功能:

  • 聊天记忆管理
  • 工具调用(Function Calling)
  • 检索增强生成(RAG)

基本使用示例

LangChain4j是 Java 生态系统中的一个流行框架,它提供了两种抽象级别:低级 API 和高级 API。其中,AI Services 是一种专为 Java 量身定制的高级 API 解决方案。以下是 LangChain4j AI Services 的最简单示例:

复制
// 定义接口
interface Assistant {
    String chat(String userMessage);
}

// 创建低级组件
ChatLanguageModel model = OpenAiChatModel.builder()
    .apiKey(System.getenv("OPENAI_API_KEY"))
    .modelName("gpt-4o-mini")
    .build();

// 创建AI Service实例
Assistant assistant = AiServices.create(Assistant.class, model);

// 使用AI Service
String answer = assistant.chat("Hello");
System.out.println(answer); // Hello, how can I help you?

使用系统消息和用户消息

lanchain4j 提供了@SystemMessage 和@UserMessage 注解来自定义提示:

复制
// 使用系统消息
interface Friend {
    @SystemMessage("You are a good friend of mine. Answer using slang.")
    String chat(String userMessage);
}

// 使用用户消息模板
interface Advisor {
    @UserMessage("You are a professional advisor. Please answer this question: {{it}}")
    String getAdvice(String question);
}

基于 Spring AI 的自定义注解实现

虽然 lanchain4j 提供了全面的解决方案,但对于已经使用 Spring AI 的项目,我们可以创建一个轻量级的自定义注解来简化集成过程。

所需依赖

首先,我们需要添加以下依赖到项目中:

复制
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.ai</groupId>
 <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

配置 ChatClient

接下来,我们需要使用 OllamaChatModel 配置 ChatClient。在 Spring 配置类中添加以下 Bean 定义:

复制
@Bean
public ChatClient chatClient(ChatModel chatModel) {
    return ChatClient.builder(chatModel)
        .defaultSystem("你是一个有用的AI助手,能够回答用户的问题并提供帮助。")
        .build();
}

创建自定义注解

现在,让我们创建@AiPrompt注解,它将用于标记需要 AI 处理的方法:

复制
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AiPrompt {
    String systemMessage() default "";
}

实现 AOP 切面

接下来,我们需要实现一个 AOP 切面来拦截带有@AiPrompt注解的方法调用:

复制
@Aspect
@Component
@RequiredArgsConstructor
publicclass AiPromptAspect {

    privatefinal ChatClient deepSeekChatClient;

    @Around("@annotation(aiPrompt)")
    public Object processAiPrompt(ProceedingJoinPoint joinPoint, AiPrompt aiPrompt) throws Throwable {
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        if (args.length == 0) {
            return joinPoint.proceed();
        }

        // 假设第一个参数是用户的输入消息
        String userMessage = args[0].toString();

        // 创建ChatClient请求
        ChatClient.ChatClientRequestSpec requestSpec = deepSeekChatClient.prompt();

        // 如果注解中指定了系统消息,则使用它
        if (!aiPrompt.systemMessage().isEmpty()) {
            requestSpec = requestSpec.system(aiPrompt.systemMessage());
        }

        return  requestSpec
                .user(userMessage)
                .call()
                .content();
    }
}

使用示例

现在,我们可以在服务类中使用@AiPrompt注解:

复制
@Service
@RequiredArgsConstructor
public class ChatService {

    @AiPrompt(systemMessage = "你是一个专业的Java开发顾问,擅长解答Spring框架相关问题。")
    public String getJavaAdvice(String question) {
        return null; // 这个返回值会被AOP切面中的返回值覆盖
    }
}

控制器示例

最后,我们可以在controller中使用这个服务:

复制
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ChatController {

    private final ChatService chatService;

    @PostMapping("/chat")
    public String getJavaAdvice(@RequestBody String question) {
        return chatService.getJavaAdvice(question);
    }
}

总结

参考 lanchain4j的高级 API 设计形式,基于 Spring AI 自定义注解实现的 AI services 可以有效地实现提示词模板的集中管理和复用,通过 AOP 机制自动处理 AI 接口的调用逻辑,显著提升开发效率。 这种模式不仅降低了与 AI 服务交互的代码复杂度,还通过标准化注解配置实现了以下优势:

  • 提示词工程的可维护性提升;
  • 业务代码与 AI 基础设施解耦;
  • 可以无缝集成 Spring 生态的其他能力,比如 Spring Cache 实现 AI 注解式缓存
相关标签:

相关资讯

中科院北大等揭示「蒸馏真相」:除Claude豆包Gemini,其他很多模型都「蒸」过头

模型蒸馏是一种将知识从大型语言模型(LLMs)转移到较小模型的技术,旨在创建资源高效且性能卓越的模型。 然而,过度蒸馏可能会导致同质化,降低模型之间的多样性,并削弱它们稳健处理复杂或新任务的能力。 这些限制凸显了系统地量化蒸馏过程及其影响的必要性。
1/22/2025 9:32:30 AM
新智元

随手一拍,高效重建大型3D开放场景,港科广GraphGS突破传统重建技术瓶颈|ICLR 2024

从手机随手拍、汽车行车记录仪到无人机航拍,如何从海量无序二维图像快速生成高精度三维场景? 传统方法依赖精确的相机位姿参数,实际应用成本高昂。 港科广团队提出全新框架GraphGS,突破技术瓶颈——无需精准相机位姿,仅凭RGB图像即可实现大规模开放场景的高效重建和高保真新视角合成,相关论文入选ICLR 2025,代码即将开源。
3/26/2025 9:55:14 AM
量子位

Spring AI + Ollama 实现 deepseek-r1 的API服务和调用

兄弟们,今天咱来聊聊一个超有意思的技术组合 ——Spring AI Ollama 实现 deepseek - r1 的 API 服务和调用。 咱都知道,人工智能这几年那可是火得一塌糊涂,各种大模型你方唱罢我登场。 deepseek - r1 就是其中一个挺厉害的模型,那怎么把它用起来,让它为咱们的项目服务呢?
3/27/2025 9:34:42 AM
儒猿团队