领先一步
VMware 提供培训和认证,助您加速进步。
了解更多我们很高兴地宣布 Spring AI 1.0.0 Milestone 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 至 ToolCallingChatOptionsChatClient.builder().defaultFunctions() 至 ChatClient.builder().defaultTools()ChatClient.functions() 至 ChatClient.tools()有关更多信息,请参阅 工具迁移指南。
工具调用功能还有其他各种改进,请查看 工具参考文档 了解更多信息。
去年 11 月,我们迎来了一个“惊喜”,而不是 10 月的惊喜:模型上下文协议 (Model Context Protocol) 发布,并受到了 AI 社区的广泛欢迎。
简而言之,模型上下文协议 (MCP) 提供了一种统一的方式来将 AI 模型连接到不同的数据源和工具,从而实现无缝且一致的集成。它帮助您在大型语言模型 (LLM) 之上构建代理和复杂的工作流。由于 LLM 经常需要与数据和工具集成,MCP 提供了
spring-ai-mcp 实验项目于去年 11 月启动,此后一直在不断发展。Spring AI 团队与 Anthropic 的 David Soria Parra 等人合作,将该实验项目整合到官方 MCP Java SDK 中。MCP Java SDK 具有以下核心功能:
还有多种传输选项
请查看 MCP Java SDK 文档,了解有关 SDK 入门的更多信息,并访问 MCP Java SDK GitHub 仓库 来提交问题和参与讨论。
随着核心组件已移至 Anthropic Java SDK,与 Spring AI 的集成侧重于提供更简单的开发体验,以利用 Spring Boot Autoconfiguration 创建客户端和服务器实现。
这是一个小型客户端示例,展示了如何在简单的聊天机器人应用程序中使用 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 作为唯一的复合键类型,而是支持
这使得与现有数据库模式和不同的 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 设计。主要更改包括:
有关破坏性更改的完整列表和详细的升级说明,请参阅参考文档中的 升级说明。