领先一步
VMware 提供培训和认证,助力您加速进步。
了解更多我们很高兴宣布发布 Spring AI 1.0.0 里程碑 6。为了庆祝此发布,我们创建了一个特别的AI 生成音乐播放列表,以增强您的博客阅读和编码体验!
与往常一样,此版本包含多项新功能和错误修复。我们继续从设计的角度审阅了代码库。虽然我们试图通过在一个发布周期内弃用方法和类来使过渡顺利,但我们知道存在一些破坏性变更,也可能存在一些我们不知道的变更,所以请大家谅解。有关详细信息,请参阅本文底部的破坏性变更部分。
函数调用的整体设计和功能集有了显著改进,现在采用了更普遍的术语“工具调用”。非常感谢 Thomas Vitale 推动了这些改进。
现在有几种定义工具的方式
@Tool
和 @ToolParam
注解的声明式方法工具以下是使用 @Tool
注解创建获取当前日期和时间的工具的示例。
import java.time.LocalDateTime;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.context.i18n.LocaleContextHolder;
class DateTimeTools {
@Tool(description = "Get the current date and time in the user's timezone")
String getCurrentDateTime() {
return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
}
}
// Using the tool with ChatClient
String response = ChatClient.create(chatModel)
.prompt("What day is tomorrow?")
.tools(new DateTimeTools())
.call()
.content();
当模型需要知道当前日期和时间时,它会自动请求调用该工具。ChatClient 在内部处理工具执行并将结果返回给模型,然后模型使用此信息生成最终响应。JSON Schema 是使用类和工具注解自动生成的。
关于弃用,org.springframework.ai.model.function
包中的所有内容都已被弃用,新的接口和类可在 org.springframework.ai.tool
包中找到。
相关 API 已更新
FunctionCallingOptions
更名为 ToolCallingChatOptions
ChatClient.builder().defaultFunctions()
更名为 ChatClient.builder().defaultTools()
ChatClient.functions()
更名为 ChatClient.tools()
请参阅工具迁移指南了解更多信息。
工具调用功能还有其他多项改进,请查阅工具参考文档了解更多信息。
与其说是“十月惊喜”,不如说是去年的“十一月惊喜”:Model Context Protocol 发布了,并受到了 AI 社区的广泛好评。
简而言之,Model Context Protocol (MCP) 提供了一种统一的方式,将 AI 模型连接到不同的数据源和工具,使集成变得无缝且一致。它帮助您在大语言模型 (LLMs) 的基础上构建代理和复杂的工作流。由于 LLMs 经常需要与数据和工具集成,MCP 提供了
spring-ai-mcp 实验项目于去年 11 月启动,并一直在发展。Spring AI 团队已与 David Soria Parra 以及 Anthropic 的其他成员合作,将该实验项目纳入官方的 MCP Java SDK。MCP Java SDK 具有以下核心功能
还有多种传输选项
请查阅 MCP Java SDK 文档,了解有关 SDK 入门的更多信息,并访问 MCP Java SDK GitHub 仓库以提交问题并参与讨论。
核心组件已移至 Anthropic Java SDK,与 Spring AI 的集成为开发人员提供了更轻松的体验,可以利用 Spring Boot 自动配置创建客户端和服务器实现。
这里有一个小的客户端示例,展示了如何在简单的聊天机器人应用程序中使用 Brave Search API
@SpringBootApplication
public class Application {
@Bean
public CommandLineRunner predefinedQuestions(
ChatClient.Builder chatClientBuilder,
ToolCallbackProvider tools,
ConfigurableApplicationContext context) {
return args -> {
var chatClient = chatClientBuilder
.defaultTools(tools)
.build();
String question = "Does Spring AI support the Model Context Protocol?";
System.out.println("ASSISTANT: " +
chatClient.prompt(question).call().content());
};
}
}
配置很简单
spring.ai.mcp.client.stdio.enabled=true
spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-servers-config.json
服务器配置是
{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-brave-search"
],
"env": {
}
}
}
}
在您的依赖配置中,导入 Spring AI Bom 并添加 Spring Boot 客户端启动器,此处显示的是 Maven 配置。
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
</dependency>
MCP 是一个很大的主题。参考文档包含更多信息,并且有多个示例
VectorStore API 已得到改进,尽管伴随了一些破坏性变更。
VectorStore 接口的 delete 方法已简化为 void 操作,移除了之前的 Optional
现在您可以根据元数据条件而不是仅仅根据文档 ID 删除文档。
以下是一个示例
// Create and add documents to the store
Document bgDocument = new Document("content",
Map.of("country", "BG", "year", 2020));
Document nlDocument = new Document("content",
Map.of("country", "NL", "year", 2021));
vectorStore.add(List.of(bgDocument, nlDocument));
// Delete documents using string filter expression
vectorStore.delete("country == 'BG'");
// Or use the Expression-based API
Filter.Expression expr = // ... your filter expression
vectorStore.delete(expr);
此功能已在所有向量存储提供商中实现,包括 Chroma、Elasticsearch、PostgreSQL、Weaviate、Redis、Milvus 等。
新的 getNativeClient()
API 允许开发人员在需要时访问底层的原生客户端实现
WeaviateVectorStore vectorStore = // get vector store
Optional<WeaviateClient> nativeClient = vectorStore.getNativeClient();
if (nativeClient.isPresent()) {
WeaviateClient client = nativeClient.get();
// Use native client capabilities
}
SimpleVectorStore 实现现在支持使用 Spring Expression Language (SpEL) 进行元数据过滤
PostgreSQL 向量存储实现已得到改进,可以更灵活地处理不同的 ID 列类型。它现在支持以下类型,而不是强制 UUID 作为唯一的 Primary Key 类型:
这使得与现有数据库 schema 和不同的 ID 管理策略的集成更加容易。
这些模型现已替换为 Amazon Bedrock Converse API,后者更灵活,并支持使用相同的 API 调用不同的模型。
每个人都在谈论代理。我们近期不会构建代理框架,因为 Anthropic 的博客文章 “构建高效代理” 引起了团队的强烈共鸣。
摘自博客文章
在过去的一年里,我们与数十个在各行业构建大语言模型 (LLM) 代理的团队合作。最成功的实现并非使用了复杂的框架或专用库。相反,它们是使用简单、可组合的模式构建的。
代理系统的两个主要类别是工作流和代理
Spring AI 已经提供了“构建块:增强型 LLM”——这是一个通过检索、工具和内存等增强功能得到加强的 LLM。利用这个构建块,博客文章描述了几种构建高效代理的工作流
有关这些模式的详细实现,请参阅 Spring AI 的 使用 Spring AI 构建高效代理(第一部分) 和配套的示例。
以下是第一个模式的示例
在本示例中,我们将创建一个链式工作流,通过以下步骤处理商业报告:
以下是使用 Spring AI 实现此模式的方法
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// Sample business report with various metrics in natural language
String report = """
Q3 Performance Summary:
Our customer satisfaction score rose to 92 points this quarter.
Revenue grew by 45% compared to last year.
Market share is now at 23% in our primary market.
Customer churn decreased to 5% from 8%.
New user acquisition cost is $43 per user.
Product adoption rate increased to 78%.
Employee satisfaction is at 87 points.
Operating margin improved to 34%.
""";
@Bean
public CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder) {
return args -> {
new ChainWorkflow(chatClientBuilder.build()).chain(report);
};
}
}
/**
* Implements a prompt chaining workflow that breaks down complex tasks into a sequence
* of simpler LLM calls, where each step's output feeds into the next step.
*/
public class ChainWorkflow {
/**
* System prompts that define each transformation step in the chain.
* Each prompt acts as a gate that validates and transforms the output
* before proceeding to the next step.
*/
private static final String[] CHAIN_PROMPTS = {
// Step 1: Extract numerical values
"""
Extract only the numerical values and their associated metrics from the text.
Format each as 'value: metric' on a new line.
Example format:
92: customer satisfaction
45%: revenue growth""",
// Step 2: Standardize to percentages
"""
Convert all numerical values to percentages where possible.
If not a percentage or points, convert to decimal (e.g., 92 points -> 92%).
Keep one number per line.
Example format:
92%: customer satisfaction
45%: revenue growth""",
// Step 3: Sort in descending order
"""
Sort all lines in descending order by numerical value.
Keep the format 'value: metric' on each line.
Example:
92%: customer satisfaction
87%: employee satisfaction""",
// Step 4: Format as markdown
"""
Format the sorted data as a markdown table with columns:
| Metric | Value |
|:--|--:|
| Customer Satisfaction | 92% |"""
};
private final ChatClient chatClient;
public ChainWorkflow(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String chain(String userInput) {
String response = userInput;
for (String prompt : CHAIN_PROMPTS) {
response = chatClient.prompt(
String.format("{%s}\n{%s}", prompt, response)
).call().content();
}
return response;
}
}
关键的数据流是每一步的输出都成为下一步的输入。对于我们的示例报告,数据流如下:
完整的源代码以及其他代理模式的实现可在 spring-ai-examples 仓库和 使用 Spring AI 构建高效代理(第一部分) 中找到。
许多贡献者进行了广泛的重构、错误修复和文档增强。如果您的 PR 尚未被处理,请耐心等待,我们会尽快处理。感谢以下贡献者:
本次发布包含几项破坏性变更,这是我们持续改进 API 设计的结果。主要变更包括
org.springframework.ai.model.function
更改为 org.springframework.ai.tool
)有关破坏性变更的完整列表和详细的升级说明,请参阅参考文档中的升级说明。