当前位置: 代码网 > it编程>编程语言>Java > Spring AI拦截器实现RAG检索的两种方式

Spring AI拦截器实现RAG检索的两种方式

2026年10月11日 • Java •我要评论
前言在 spring ai 中,advisor api 本质上就是对话调用链上的拦截器。它位于用户 prompt 和大模型调用之间,可以在请求发出前对 prompt 做增强,也可以在响应返回后做处理。

前言

在 spring ai 中,advisor api 本质上就是对话调用链上的拦截器。它位于用户 prompt 和大模型调用之间,可以在请求发出前对 prompt 做增强,也可以在响应返回后做处理。

用 advisor 实现向量数据库的 rag 检索,核心是 questionansweradvisor。这个内置拦截器的工作方式很直接:拦截用户 prompt,在绑定的 vectorstore 中执行相似度搜索,把检索到的文档片段拼进 prompt 的 {question_answer_context} 占位符,再交给模型生成答案。

根据检索范围的固定还是动态,有两种实现方式。两者都通过 defaultadvisors 注册,区别只在调用时是否额外传入过滤参数。

方式一:全局共用一份知识库

questionansweradvisor 在构建时就绑定了 vectorstore,注册为 defaultadvisors 后,每次对话自动走同一个检索逻辑,对整个向量库执行相似度搜索。

@configuration
public class ragconfig {

    @bean
    public questionansweradvisor questionansweradvisor(vectorstore vectorstore) {
        return questionansweradvisor.builder(vectorstore)
            .searchrequest(searchrequest.builder()
                .topk(4)
                .similaritythreshold(0.8)
                .build())
            .build();
    }

    @bean
    public chatclient chatclient(chatmodel chatmodel, 
                                 questionansweradvisor questionansweradvisor) {
        return chatclient.builder(chatmodel)
            .defaultadvisors(questionansweradvisor)   // 全局注册
            .build();
    }
}

调用时不需要在每次 prompt() 里重复指定任何东西:

string answer = chatclient.prompt()
    .user("spring ai 的 advisor 是什么?")
    .call()
    .content();

topk 控制返回的文档片段数量,similaritythreshold 是相似度得分下限。两者的配合逻辑是:先按阈值过滤低质量候选,再取前 k 个。similaritythreshold 设为 0.8 意味着只接受相似度 80 分以上的文档片段。

这种方式适合所有对话共享同一套知识的场景,配置最简单,但无法按用户或业务类型收窄检索范围。

方式二:每次对话动态过滤

同样注册为 defaultadvisors,但允许在运行时通过 filter_expression 参数覆盖或细化检索范围。过滤表达式采用类似 sql 的语法,可移植于所有 vectorstore 实现。

@bean
public chatclient chatclient(chatmodel chatmodel, vectorstore vectorstore) {
    questionansweradvisor qaadvisor = questionansweradvisor.builder(vectorstore)
        .searchrequest(searchrequest.builder()
            .topk(4)
            .build())
        .build();

    return chatclient.builder(chatmodel)
        .defaultadvisors(qaadvisor)   // 同样注册为默认 advisor
        .build();
}

调用时传入过滤条件:

string answer = chatclient.prompt()
    .user("我的订单有什么问题?")
    .advisors(a -> a.param(
        questionansweradvisor.filter_expression,
        "user_id == '12345' && type == 'order'"))
    .call()
    .content();

底层会先通过元数据字段缩小候选集,再在候选集内执行向量相似度计算。如果同时在 advisor 构建时设置了基础过滤表达式,运行时传入的表达式优先级更高,会覆盖构建时的配置。

这种方式适合多租户、多业务线、需要权限隔离的场景,同一份向量库可以为不同对话提供不同范围的检索结果。

两种方式的核心区别

两种实现都使用了 defaultadvisors,questionansweradvisor 都是通过 chatclient.builder().defaultadvisors(...) 注册的。区别只在于调用时是否额外传入运行时参数来收窄检索范围。

维度方式一:全局共用方式二:动态过滤
defaultadvisors有有
检索范围整个向量库过滤后的子集
调用时的 advisors()不传传 filter_expression
隔离能力无按用户/租户/业务类型隔离
适用场景统一知识库问答多租户、多业务线、权限控制

方式一是“注册后就固定”,方式二是“注册后每次还能改”。

一个配置层面的细节

questionansweradvisor 的默认 similaritythreshold 是 0.0,意味着接受所有匹配结果,不管相似度多低。在生产环境中,这通常不是想要的行为。设置一个合理的阈值,可以让模型在检索不到相关内容时更诚实地表示“不知道”,而不是基于弱相关片段给出看似自信的错误回答。

阈值和 topk 的交互也需要留意:高阈值配高 topk,如果没有任何文档越过阈值线,模型会退回使用自己的知识库回答;阈值越低,越多的低质量匹配会进入 prompt,可能干扰模型判断。

以上就是spring ai拦截器实现rag检索的两种方式的详细内容,更多关于spring ai拦截器实现rag检索的资料请关注代码网其它相关文章!

赞 (0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com