一般情况,我们会涉及到一个重要的业务逻辑,就是对提问的敏感词进行过滤,在springAi中实现的方法也很简单,只需要在bean中添加一个SafeGuardAdvisor就可以了
@Bean(name = "openAiChatClient")
public ChatClient openrouterChatClient(OpenAiChatModel openAiChatModel) {
OpenAiChatOptions openAiChatOptions = new OpenAiChatOptions();
openAiChatOptions.setModel("openai/gpt-5-mini");
List<String> list = List.of("郭雲铨", "trump", "drug");
SafeGuardAdvisor safeGuardAdvisor = new SafeGuardAdvisor(list,"你想害死我啊,别瞎打听",0);
WriterAdvisor writerAdvisor = new WriterAdvisor();
return ChatClient
.builder(openAiChatModel).
defaultAdvisors(safeGuardAdvisor).
defaultOptions(openAiChatOptions)
.build();
}这个例子就是当触发"郭雲铨", "trump", "drug"这些关键词时候,不调用大模型,直接返回违禁结果
这是正常提问,正常回答

然后提问违禁词

这个里面关键实现了SafeGuardAdvisor,查看了一下文档,springAi是可以写拦截切面的(调用之前和调用之后),写一个对用户提问重写的例子
package com.gyq.config;
import org.jetbrains.annotations.NotNull;
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.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import java.util.Map;
public class WriterAdvisor implements BaseAdvisor {
private static final String mutatePrompt = """
你作为一个心血管方面的专家,请对我的问题进行深度理解,在你的回答中要有你职业的介绍
{question}
""";
/**
* Logic to be executed before the rest of the advisor chain is called.
*/
@NotNull
@Override
public ChatClientRequest before(ChatClientRequest chatClientRequest, @NotNull AdvisorChain advisorChain) {
String contents = chatClientRequest.prompt().getContents();
String question = PromptTemplate.builder().template(mutatePrompt).build()
.render(Map.of("question", contents));
return chatClientRequest
.mutate()
.prompt(Prompt.builder().content(question).build())
.build();
}
/**
* Logic to be executed after the rest of the advisor chain is called.
*/
@NotNull
@Override
public ChatClientResponse after(@NotNull ChatClientResponse chatClientResponse, @NotNull AdvisorChain advisorChain) {
return chatClientResponse;
}
@Override
public int getOrder() {
return 0;
}
}
然后接口调用新增WriterAdvisor
@GetMapping(value ="/openAi", produces = "text/stream;charset=UTF-8")
public Flux<String> openAiChat(@RequestParam("userPrompt") String userPrompt) {
return openAiChatClient
.prompt().advisors(new WriterAdvisor())
.user(userPrompt)
.stream()
.content();
}最终实现效果就是