一.背景
在生成式 AI 技术快速普及的当下,Spring AI 作为 Spring 生态专为 AI 应用开发打造的框架,凭借其与 Spring Boot、Spring Cloud 等核心组件的无缝集成能力,大幅降低了开发者构建 AI 应用的门槛,成为 Java 生态中落地生成式 AI 场景的优选方案。Function Call(函数调用)作为大语言模型(LLM)突破 “仅生成文本” 局限的核心能力,允许模型根据用户需求自主识别并调用外部工具(如数据库查询、API 调用、文件处理等),将 AI 的推理能力与现实世界的业务系统深度联动,广泛应用于智能助手、自动化流程、数据查询分析等场景。
在传统 AI 应用开发中,若需实现 LLM 与外部工具的协同,开发者需手动处理复杂的交互逻辑:包括设计提示词引导模型输出结构化指令、解析模型返回的非标准格式数据、处理工具调用的参数校验与异常捕获、管理多轮调用的上下文状态等。这不仅导致代码冗余、耦合度高,还面临跨工具适配、格式兼容性、上下文丢失等问题,尤其在 Java 生态中,缺乏统一的函数调用规范和集成框架,进一步提升了开发成本与维护难度。
Spring AI 针对这一痛点,提供了标准化的 Function Call 封装能力:通过注解驱动的函数注册、统一的参数解析机制、内置的上下文管理与多轮调用支持,将 LLM 的函数调用能力与 Spring 生态的开发范式深度融合。开发者无需关注底层的格式解析、工具适配等细节,即可快速实现 LLM 与业务系统的联动,让 AI 模型成为业务流程的 “智能调度者”。
然而,在实际落地过程中,开发者仍面临诸多实践挑战:如何合理设计函数签名以适配 LLM 的理解能力、如何处理复杂参数的校验与类型转换、如何实现多轮函数调用中的上下文衔接、如何兼容不同 LLM 厂商(如 OpenAI、Azure OpenAI、本地化模型)的函数调用协议差异等。因此,开展 Spring AI Function Call 的使用尝试,不仅是探索其在 Java 生态中落地可行性的关键步骤,更是为了解决上述实践痛点,沉淀标准化的开发流程与最佳实践,为后续构建复杂 AI 业务系统(如智能办公助手、实时数据查询机器人、自动化运维工具等)奠定基础,具有重要的技术探索价值与工程实践意义。
二.具体实现
1.定义工具函数
/**
* 提取实体函数tool定义
*/
public static final String MEMORA_EXTRACT_ENTITIES_TOOL = "{\n" +
"\t\"type\": \"object\",\n" +
"\t\"properties\": {\n" +
"\t\t\"entities\": {\n" +
"\t\t\t\"type\": \"array\",\n" +
"\t\t\t\"items\": {\n" +
"\t\t\t\t\"type\": \"object\",\n" +
"\t\t\t\t\"properties\": {\n" +
"\t\t\t\t\t\"entity\": {\n" +
"\t\t\t\t\t\t\"type\": \"string\",\n" +
"\t\t\t\t\t\t\"description\": \"The name or identifier of the entity.\"\n" +
"\t\t\t\t\t},\n" +
"\t\t\t\t\t\"entity_type\": {\n" +
"\t\t\t\t\t\t\"type\": \"string\",\n" +
"\t\t\t\t\t\t\"description\": \"The type or category of the entity.\"\n" +
"\t\t\t\t\t}\n" +
"\t\t\t\t},\n" +
"\t\t\t\t\"required\": [\"entity\", \"entity_type\"],\n" +
"\t\t\t\t\"additionalProperties\": false\n" +
"\t\t\t},\n" +
"\t\t\t\"description\": \"An array of entities with their types.\"\n" +
"\t\t}\n" +
"\t},\n" +
"\t\"required\": [\"entities\"],\n" +
"\t\"additionalProperties\": false\n" +
"}";
2.定义工具列表
List<OpenAiApi.FunctionTool> tools = List.of(
new OpenAiApi.FunctionTool(new OpenAiApi.FunctionTool.Function(
"Extract entities and their types from the text.",
"extract_entities",
MEMORA_EXTRACT_ENTITIES_TOOL
))
);
3.构建大模型调用
// 创建模型选项,指定模型名称和其他参数
OpenAiChatOptions options = OpenAiChatOptions.builder()
.model(model)
.temperature(0.8)
.maxTokens(2048)
.tools(tools)
.toolChoice("auto")
.build();
List<Message> content = new ArrayList<>();
content.add(new UserMessage(userContent));
content.add(new SystemMessage(systemContent));
// 创建包含选项的Prompt
Prompt prompt = new Prompt(content, options);
// 调用模型获取响应
ChatResponse response = openAiChatModel.call(prompt);
4.大模型返回结果如下:
请求参数:
{
"userContent":"我爱吃饭",
"systemContent":"你是一款能够理解文本中实体及其类型的智能助手。若用户消息包含 “我”“我自己”“我的” 等自指表述,需将 123 作为源实体。请从文本中提取所有实体。如果给定文本是一个问题,切勿回答问题本身。"
}
返回结果:
{
"name": "functions.extract_entities",
"arguments": {
"entities": [
{
"entity": "123",
"entity_type": "person"
}
]
}
}
1186

被折叠的 条评论
为什么被折叠?



