【AI应用开发捷径之路】第六课:SpringAi中的对话拦截机制

2025-12-30 09:34:56
文章摘要
Spring AI中的拦截器(Advisors)是其核心架构的重要组成部分,它借鉴了Spring AOP(面向切面编程)的设计理念,为AI驱动的交互提供了强大而灵活的拦截、修改和增强能力。

文章转载自[DAT数智AI技术 ]

原创 小数先生

 定义

Spring AI中的拦截器(Advisors)是其核心架构的重要组成部分,它借鉴了Spring AOP(面向切面编程)的设计理念,为AI驱动的交互提供了强大而灵活的拦截、修改和增强能力。下面我将详细扩展这一知识点的各个方面。

Spring AI的Advisors本质上是一种声明式的拦截机制,它允许开发者在AI调用的关键生命周期节点插入自定义逻辑,而无需修改核心业务代码。这种设计带来的核心价值包括:

非侵入式增强:通过配置而非代码修改来添加功能

关注点分离:将横切关注点(如日志、监控、缓存)与业务逻辑分离

可复用性:同一Advisor可应用于多个不同的AI交互场景

组合性:多个Advisors可以组合使用,形成处理链



Spring 应用程序中的 AI 驱动交互

1、实现日志的拦截记录

调整日志的模式为DEBUG


# 日志配置用于调试

logging:

  level:

    org.springframework.ai: DEBUG

    org.springframework.web.client: TRACE


实现代码的输出

package com.example.base;


import cn.myeasyai.FaceApplication;

import org.junit.jupiter.api.Test;

import org.springframework.ai.chat.client.ChatClient;

import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;

import org.springframework.ai.deepseek.DeepSeekChatModel;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;


@SpringBootTest(classes = FaceApplication.class)

public class TestAdvisor {



    @Autowired

    DeepSeekChatModel deepSeekChatModel;

    @Test

    public void testAdvisor() {

        ChatClient.Builder builder = ChatClient.builder(deepSeekChatModel);

        ChatClient build = builder

                .defaultAdvisors(new SimpleLoggerAdvisor())  //加入一个日志拦截器,输出更详细的日志信息

                .build();


        ChatClient.CallResponseSpec content = build.prompt()

                .user("你好")

                .call();

        String content1 = content.content();

        System.out.println(content1);



    }


}


2、实现敏感词拦截

 new SafeGuardAdvisor(List.of("您好")))  //加入一个敏感词的拦截器,当用户输入敏感词时,会返回一个提示

package com.example.base;


import cn.myeasyai.FaceApplication;

import org.junit.jupiter.api.Test;

import org.springframework.ai.chat.client.ChatClient;

import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;

import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;

import org.springframework.ai.deepseek.DeepSeekChatModel;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;


import java.util.List;


@SpringBootTest(classes = FaceApplication.class)

public class TestAdvisor {



    @Autowired

    DeepSeekChatModel deepSeekChatModel;

    @Test

    public void testAdvisor() {

        ChatClient.Builder builder = ChatClient.builder(deepSeekChatModel);

        ChatClient build = builder

                .defaultAdvisors(new SimpleLoggerAdvisor(),

                        new SafeGuardAdvisor(List.of("您好")))  //加入一个敏感词的拦截器,当用户输入敏感词时,会返回一个提示

                .build();


        ChatClient.CallResponseSpec content = build.prompt()

                .user("您好")

                .call();

        String content1 = content.content();

        System.out.println(content1);



    }


}


3、自定义拦截器重写用户提示词

自定义拦截器重读(Re2)

重读策略的核心在于让LLMs重新审视输入问题,这借鉴了人类解决问题的思维方式。通过这种方式LLMs能够更深入地理解问题,发现复杂的模式,从而在各种推理任务中表现得更加强大。

{Input_Query}

再次阅读问题:{Input_Query}

可以基于BaseAdvisor来实现自定义Advisor,他实现了重复的代码 提供 模板方法让我们可以专注自己业务编写即可。

package cn.myeasyai.Service;


import org.springframework.ai.chat.client.ChatClientRequest;

import org.springframework.ai.chat.client.ChatClientResponse;

import org.springframework.ai.chat.client.advisor.api.AdvisorChain;

import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;

import org.springframework.ai.chat.client.advisor.api.CallAdvisor;

import org.springframework.ai.chat.prompt.Prompt;

import org.springframework.ai.chat.prompt.PromptTemplate;


import java.util.Map;


public class ReReadingAdvisor implements BaseAdvisor {


    private  static  final String DEFAULT_USER_TEXT_ADVISE = """

            {re2_input_query}

            Read the question again: {re2_input_query}

            """;

    @Override

    public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {

        // TODO: Implement 请求之前重写提示词

        //用户提示词

        String contents = chatClientRequest.prompt().getContents();


        String re2InputQuery = PromptTemplate.builder().template(DEFAULT_USER_TEXT_ADVISE).build().render(Map.of("re2_input_query", contents));


        ChatClientRequest build = chatClientRequest.mutate()

                .prompt(Prompt.builder().content(re2InputQuery).build())

                .build();


        return build;

    }


    @Override

    public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {

        // TODO: Implement 响应之后重写结果

        return null;

    }


    @Override

    public int getOrder() {

        return 0;

    }

}

测试

package com.example.base;


import cn.myeasyai.FaceApplication;

import cn.myeasyai.Service.ReReadingAdvisor;

import org.junit.jupiter.api.Test;

import org.springframework.ai.chat.client.ChatClient;

import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;

import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;

import org.springframework.ai.deepseek.DeepSeekChatModel;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;


import java.util.List;


@SpringBootTest(classes = FaceApplication.class)

public class TestAdvisor {



    @Autowired

    DeepSeekChatModel deepSeekChatModel;



    @Test

    public void testReReadingAdvisor() {

        ChatClient.Builder builder = ChatClient.builder(deepSeekChatModel);

        ChatClient build = builder

                .defaultAdvisors(new SimpleLoggerAdvisor(),

                        new ReReadingAdvisor())  //重写提示词的拦截器

                .build();


        ChatClient.CallResponseSpec content = build.prompt()

                .user("发哥帅不帅")

                .call();

        String content1 = content.content();

        System.out.println(content1);


    }


}

可以看到,用户的提示词被修改了


通过合理设计和组合Advisors,可以构建出既强大又灵活的AI服务架构,在保持代码整洁的同时,实现复杂的企业级需求。在实际应用中,建议从简单的Advisor开始,逐步构建复杂的拦截链,并始终关注性能影响和可维护性。

声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。