本课目标

理解 Advisor 链式模型,会写自定义 Advisor,实现日志、安全审查、上下文增强等横切逻辑。


你发现每个 AI 接口都要做同一套事:记日志、限 Token、过滤敏感词、注入系统提示词。如果每个接口里都写一遍这些逻辑,代码就是灾难。

Spring MVC 用 Interceptor 解决了 HTTP 层的横切关注点。Spring AI 用 Advisor 解决了 AI 调用层的横切关注点——在模型调用前后插入自定义逻辑,多个 Advisor 串成链。前面学的记忆、RAG,本质都是内置 Advisor。本讲教你理解这条链,并写出自己的 Advisor。

核心内容

链式模型:请求往下走,响应往回走

请求先经过 Advisor A → Advisor B → 模型调用。响应沿原路返回:模型 → Advisor B → Advisor A。每一层都可以改写请求和响应。order 决定执行顺序——安全审查必须最先执行(HIGHEST_PRECEDENCE),日志可以最后。

跟 Spring Security 的 Filter Chain 一个思路。你写过的 Interceptor、切面、Filter,Advisor 就是它们在 AI 调用层的对应物。

内置 Advisor 速览

Advisor 用途
MessageChatMemoryAdvisor 对话记忆(第 05 讲)
QuestionAnswerAdvisor RAG 检索增强(第 06 讲)
SimpleLoggerAdvisor 请求/响应日志
SafeGuardAdvisor 敏感词拦截

自定义 Advisor:实现 CallAdvisor 接口

public class TokenBudgetAdvisor implements CallAdvisor {

    @Override
    public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
        // 前置:估算 prompt token,超预算直接拒绝
        if (estimateTokens(request.prompt()) > MAX_BUDGET) {
            return ChatClientResponse.builder()
                .chatResponse(rejectResponse())
                .build();
        }
        ChatClientResponse response = chain.nextCall(request);
        // 后置:记录实际消耗
        meterRegistry.counter("llm.tokens",
            "model", modelName).increment(actualTokens(response));
        return response;
    }

    @Override public String getName() { return "TokenBudgetAdvisor"; }
    @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE + 100; }
}

这个 Advisor 的精髓在于"拒绝前置"——不需要等模型响应就能判断该不该放行。把昂贵的模型调用拦截在最前面,省 Token 就是省钱。

灵枢 OS 的 Advisor 实战组合

  • 成本护栏:Token 预算 + 限流,防止单个会话把额度烧光。这个 Advisor 的 order 设为最高优先级。
  • 审计日志:全量记录每次请求/响应。Agent 行为可追溯是合规刚需,尤其是面向企业客户的平台。
  • 动态系统提示词:按租户/场景注入不同 system 文本。一个 SaaS 产品服务多个客户,每个客户有不同的术语和规范——Advisor 在请求阶段根据 tenantId 注入对应的 system prompt。
  • 跨 Advisor 传数据:用 context map,别用 ThreadLocal。流式场景下请求可能跨线程执行,ThreadLocal 里的数据会丢。

Advisor 和 Tool 都能"增强"模型。边界在哪?Tool 解决"信息不足"——模型不知道数据,Tool 去查。Advisor 解决"横切关注"——每次调用都要做的事,与具体业务无关。模型主动调 Tool;Advisor 被动拦截。

动手练习

  1. 写一个 Token 预算 Advisor,超过 5000 token 直接拒绝
  2. 串联 SimpleLoggerAdvisor + 你的 TokenBudgetAdvisor,观察执行顺序