抢先一步
VMware 提供培训和认证,助您快速提升。
了解更多在快速发展的人工智能世界中,开发者不断寻求增强其 AI 应用的方法。Spring AI,一个用于构建 AI 驱动应用的 Java 框架,引入了一个强大的特性:Spring AI Advisors。
这些 Advisor 可以极大地增强您的 AI 应用,使其更加模块化、可移植且易于维护。
如果不方便阅读本文,您可以收听这个实验性播客,它是根据博客内容AI 生成的
其核心在于,Spring AI Advisors 是拦截并可能修改 AI 应用中聊天补全请求和响应流程的组件。该系统中的关键参与者是 AroundAdvisor,它允许开发者在这些交互中动态转换或利用信息。
使用 Advisors 的主要优势包括
Advisor 系统以链式方式运作,序列中的每个 Advisor 都有机会处理传入请求和传出响应。以下是一个简化流程:
AdvisedRequest
,并带有一个空的 advisor-context
。AdvisedResponse
通过 Advisor 链传回,它是原始 ChatResponse
和链输入路径中的 advise context 的组合。AdvisedResponse
中增强的 ChatResponse
返回给客户端。Spring AI 提供了几个预构建的 Advisors,用于处理常见场景和生成式 AI 模式
使用 ChatClient API,您可以注册您的管道所需的 Advisors
var chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(
new MessageChatMemoryAdvisor(chatMemory), // chat-memory advisor
new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()) // RAG advisor
)
.build();
String response = chatClient.prompt()
// Set chat memory parameters at runtime
.advisors(advisor -> advisor.param("chat_memory_conversation_id", "678")
.param("chat_memory_response_size", 100))
.user(userText)
.call()
.content();
Advisor API 包括用于非流式场景的 CallAroundAdvisor 和 CallAroundAdvisorChain,以及用于流式场景的 StreamAroundAdvisor 和 StreamAroundAdvisorChain。它还包括用于表示未封装的 Prompt 请求数据的 AdvisedRequest 和用于聊天补全数据的 AdvisedResponse。AdvisedRequest 和 AdvisedResponse 都有一个 advise-context
字段,用于在整个 Advisor 链中共享状态。
创建自定义 Advisor 很简单。让我们来实现一个简单的日志记录 Advisor 来演示整个过程
public class SimpleLoggerAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {
private static final Logger logger = LoggerFactory.getLogger(SimpleLoggerAdvisor.class);
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Override
public int getOrder() {
return 0;
}
@Override
public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {
logger.debug("BEFORE: {}", advisedRequest);
AdvisedResponse advisedResponse = chain.nextAroundCall(advisedRequest);
logger.debug("AFTER: {}", advisedResponse);
return advisedResponse;
}
@Override
public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
logger.debug("BEFORE: {}", advisedRequest);
Flux<AdvisedResponse> advisedResponses = chain.nextAroundStream(advisedRequest);
return new MessageAggregator().aggregateAdvisedResponse(advisedResponses,
advisedResponse -> logger.debug("AFTER: {}", advisedResponse));
}
}
这个 Advisor 会在请求处理前和响应接收后记录日志,为 AI 交互过程提供有价值的洞察。
aggregateAdvisedResponse(...)
工具将 AdvisedResponse
块组合成一个单一的 AdvisedResponse
,返回原始流并接受一个 Consumer
回调来处理完成的结果。它保留了原始内容和上下文。
让我们基于重读 (Re2) 技术实现一个更高级的 Advisor,该技术受这篇论文启发,可以提高大型语言模型的推理能力
public class ReReadingAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {
private static final String DEFAULT_USER_TEXT_ADVISE = """
{re2_input_query}
Read the question again: {re2_input_query}
""";
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Override
public int getOrder() {
return 0;
}
private AdvisedRequest before(AdvisedRequest advisedRequest) {
String inputQuery = advisedRequest.userText(); //original user query
Map<String, Object> params = new HashMap<>(advisedRequest.userParams());
params.put("re2_input_query", inputQuery);
return AdvisedRequest.from(advisedRequest)
.withUserText(DEFAULT_USER_TEXT_ADVISE)
.withUserParams(params)
.build();
}
@Override
public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {
return chain.nextAroundCall(before(advisedRequest));
}
@Override
public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
return chain.nextAroundStream(before(advisedRequest));
}
}
这个 Advisor 修改输入查询以包含一个“重读”步骤,可能提高 AI 模型对问题的理解和推理能力。
Spring AI 的高级主题涵盖了 Advisor 管理的重要方面,包括顺序控制、状态共享和流式处理能力。Advisor 的执行顺序由 getOrder() 方法决定。通过共享的 advise-context 对象,可以实现 Advisor 之间的状态共享,从而促成复杂的多 Advisor 场景。该系统支持流式和非流式 Advisors,允许处理完整的请求和响应,或使用响应式编程概念处理连续数据流。
链中 Advisors 的顺序至关重要,它由 getOrder()
方法决定。order 值较低的 Advisors 首先执行。由于 Advisor 链是一个栈,链中的第一个 Advisor 是最后一个处理请求和第一个处理响应的。如果您想确保某个 Advisor 最后执行,请将其 order 值设置接近 Ordered.LOWEST_PRECEDENCE
;反之,如果想使其首先执行,请将其 order 值设置接近 Ordered.HIGHEST_PRECEDENCE
。如果多个 Advisors 的 order 值相同,则执行顺序无法保证。
AdvisedRequest
和 AdvisedResponse
都共享一个 advise-context 对象。您可以使用 advise-context
在链中的 Advisors 之间共享状态,并构建涉及多个 Advisors 的更复杂的处理场景。
Spring AI 同时支持流式和非流式 Advisors。非流式 Advisors 处理完整的请求和响应,而流式 Advisors 使用响应式编程概念(例如,用于响应的 Flux)处理连续的数据流。
对于流式 Advisors,需要注意的是,单个 AdvisedResponse
实例仅表示整个 Flux<AdvisedResponse>
响应的一部分(即一个块)。相比之下,对于非流式 Advisors,AdvisedResponse
包含完整的响应。
advise-context
在 Advisors 之间共享状态。Spring AI Advisors 提供了一种强大且灵活的方式来增强您的 AI 应用。通过利用这个 API,您可以创建更复杂、可复用且易于维护的 AI 组件。无论您是实现自定义逻辑、管理对话历史,还是改进模型推理,Advisors 都提供了一个清晰高效的解决方案。
我们鼓励您在项目中尝试 Spring AI Advisors,并与社区分享您的自定义实现。可能性是无限的,您的创新可以帮助塑造 AI 应用开发的未来!
编程愉快,愿您的 AI 应用越来越智能和响应迅速!