Spring AI Advisor:一行代码解决 AI 应用"面条代码"

别再每次调用 AI 都写重复的鉴权、日志、敏感词检测代码了------Spring AI Advisor 给你一条可复现的路,把横切逻辑像乐高一样拆装。

先附上一张Spring AI Advisor架构图

先给结论

Spring AI Advisor 是一个可插拔的请求/响应增强机制,通过责任链模式组合多个横切关注点,让 AI 应用的横切逻辑管理变得简单优雅。

为什么需要 Advisor

没有 Advisor 时,每次调用都要写一堆重复代码:

java 复制代码
public String callAI(String input) {
    if (!authService.check(input)) return "无权限";
    if (containsSensitiveWords(input)) return "敏感内容";
    List<ChatMessage> history = memoryService.getHistory();
    ChatResponse response = model.call(new Prompt(input, history));
    logger.info("调用AI:输入={},输出={}", input, response);
    memoryService.save(input, response);
    if (checkOutput(response)) return "输出有风险";
    return response.getContent();
}

有 Advisor 后,业务代码回归干净:

java 复制代码
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(
        new AuthAdvisor(),
        new SensitiveWordAdvisor(),
        new MessageChatMemoryAdvisor(chatMemory),
        new MyLoggerAdvisor()
    )
    .build();

String answer = chatClient.prompt().user("你好").call().content();

Advisor 的核心原理

1. 责任链模式

  • 前置处理:按 Order 值升序执行(值小先执行)
  • 后置处理:按 Order 值降序执行(后进先出)
  • 短路机制:某个 Advisor 可以直接返回,不继续调用模型

2. 短路能力

java 复制代码
public class SensitiveWordAdvisor implements CallAroundAdvisor {
    @Override
    public AdvisedResponse aroundCall(AdvisedRequest req, CallAroundAdvisorChain chain) {
        for (String word : blockedWords) {
            if (req.userText().contains(word)) {
                AssistantMessage rejection = new AssistantMessage("抱歉,内容不合规,无法回答。");
                ChatResponse chatResponse = new ChatResponse(List.of(new Generation(rejection)));
                return AdvisedResponse.from(chatResponse).advisorContext(req.advisorContext()).build();
            }
        }
        return chain.nextAroundCall(req);
    }
}

3. 自定义 Advisor 四步

  1. 同时实现 CallAroundAdvisor + StreamAroundAdvisor
  2. 重写 aroundCall/aroundStream
  3. 设置 getOrder()
  4. 返回唯一 getName()

实战案例:RAG + Advisor

java 复制代码
@Service
public class KnowledgeService {
    private final ChatClient chatClient;

    public KnowledgeService(ChatClient.Builder builder, VectorStore vectorStore) {
        this.chatClient = builder
            .defaultSystem("请基于提供的上下文信息回答问题,上下文不足就明确说明,不要编造。")
            .defaultAdvisors(
                new QuestionAnswerAdvisor(vectorStore),
                new AuthAdvisor(),
                new MyLoggerAdvisor()
            )
            .build();
    }

    public String ask(String question) {
        return chatClient.prompt().user(question).call().content();
    }
}

踩坑清单

Order 排序

java 复制代码
new MyLoggerAdvisor(),         // Order=0,最外层
new SecurityAdvisor(),         // Order=10,安全检查
new RagAdvisor(vectorStore),    // Order=50,RAG 检索增强
new MemoryAdvisor(chatMemory)   // Order=100,最靠近模型

流式处理

java 复制代码
// 错误:对每个 token 触发
chain.nextAroundStream(request).doOnNext(this::afterProcess)

// 正确:聚合完整响应
new MessageAggregator().aggregateAdvisedResponse(
    chain.nextAroundStream(request), this::logAfter)

避免耗时操作

Advisor 同步执行,别在链里做外部 API 调用或复杂计算。

不适用的情况

  1. 需要异步处理时,Advisor 是同步的
  2. 复杂并行场景,责任链是串行的
  3. 性能敏感场景,多个 Advisor 会增加调用开销
相关推荐
零依赖极客18 小时前
《30 天手搓 ARM 架构零依赖纯 C 推理引擎》课程介绍与大纲
c语言·开发语言·arm开发·人工智能·嵌入式硬件·ai编程
Behaviour19 小时前
DeepSeek V4.1 Flash 发布开源,Harness v0.1.5同日适配
人工智能·语言模型·开源·aigc·ai编程
Bigger20 小时前
我把苹果发布会里的折叠屏,真的用网页做出来了
前端·ai编程·交互设计
孟健20 小时前
实测DeepSeek V4.1 Flash:调用费不到1元拿到补丁
ai编程
善良勤劳勇敢而又聪明的老杨1 天前
【AI编程系列】MCP 常用设计模式解读
设计模式·ai编程
VIP_CQCRE1 天前
把 OpenCode 接入 Ace Data Cloud:让 AI 编程能力真正进入 IDE 工作流
大模型·ai编程·开发工具·opencode·acedatacloud
亦暖筑序1 天前
AgentScope Java 实战:@Tool 方法里到底该不该写业务逻辑?
java·agent·ai编程
vibecoding771 天前
一文搞懂企业级 API 网关选型:12 个维度、4 类企业、7 步落地
人工智能·大模型·ai编程
旋生万物2 天前
量子纠错容错率87%?螺旋拓扑码用“相位保护“给量子比特上保险(附Python)
python·ai编程·量子计算·量子纠错·螺旋计算