type
status
date
slug
summary
tags
category
icon
password
catalog
sort
在当今数字化转型的浪潮中,人工智能(AI)技术正逐渐成为推动业务创新的关键力量。Spring AI 作为 Spring 生态系统中的一员,为开发者提供了一种简单而高效的方式来集成 AI 功能。作为一名专注于 Java 技术的开发者,我深入研究了 Spring AI 的架构、核心模块以及其实现方式,并在此分享我的学习心得和实践代码。

Spring AI 架构概览

Spring AI 的架构设计旨在简化 AI 技术的集成,其核心理念是让开发者专注于业务逻辑,而非底层技术细节。整个架构可以分为以下几个关键部分:

1. 核心模块分类

Spring AI 的功能模块主要分为以下几类:
  • AI 模型集成模块:支持多种流行的 AI 模型和服务,如 OpenAI、Azure OpenAI、Anthropic Claude 等。
  • 向量数据库支持模块:提供与多种向量数据库的集成,包括 SQL 和 NoSQL 数据库,以及专用的向量数据库。
  • 文档处理模块:支持多种文档格式的读取和处理,如 Markdown、PDF 等。
  • 对话记忆存储模块:用于存储和管理聊天历史,支持基于 JDBC、Cassandra 和 Neo4j 的存储。
  • 优化求解模块:提供 AI 求解器,用于优化操作和调度问题。

2. 架构时序图

为了更好地理解 Spring AI 的工作流程,我们可以用时序图来描述其典型的工作流程。以下是一个简化的时序图:

核心模块详解

1. AI 模型集成模块

1.1 大型语言模型 (LLM) 支持

Spring AI 支持多种流行的 LLM 服务,如 OpenAI、Azure OpenAI 等。这些服务提供了强大的自然语言处理能力,可以用于生成文本、回答问题等。

1.2 嵌入模型

嵌入模型将文本或多模态内容转换为向量表示,是实现语义搜索、推荐系统等功能的基础。Spring AI 支持多种嵌入模型,如 Google 的 Vertex AI Embeddings、Amazon Bedrock 等。

1.3 图像生成模型

Spring AI 还支持图像生成模型,如 Stability AI 和 OpenAI DALL-E,可以用于根据文本描述生成图像。

2. 向量数据库支持模块

向量数据库是 AI 应用的重要组成部分,用于存储和检索嵌入向量。Spring AI 提供了丰富的向量数据库集成选项,包括 PostgreSQL 的 PGvector、MongoDB Atlas 的向量数据库等。

3. 文档处理模块

Spring AI 提供了多种文档读取和处理工具,能够从不同格式的文档中提取文本并转换为 Spring AI Document 对象。支持的文档格式包括 Markdown、PDF 等。

4. 对话记忆存储模块

这些模块提供了存储和管理聊天历史的功能,对于构建具有上下文感知能力的对话应用至关重要。支持基于 JDBC、Cassandra 和 Neo4j 的存储。

5. 优化求解模块

Spring AI 提供了 AI 求解器,如 Timefold Solver,用于优化操作和调度问题。

核心模块示范代码

以下是一个基于 Spring AI 的简单聊天应用的示范代码,展示了如何使用 Ollama 本地运行的 LLM 模型。

1. Maven 依赖

首先,需要添加 Spring AI 的 Maven 依赖:

2. 配置文件

配置 Ollama 客户端的连接信息:

3. 控制器代码

创建一个简单的 REST 控制器,用于接收用户输入并调用 Ollama 模型生成响应:

4. 运行前准备

在运行代码之前,需要确保 Ollama 已安装并运行,并且已拉取所需的模型:

5. 示例响应

访问 /ai/generate 接口,传入消息参数,即可获取由 Ollama 模型生成的响应:

 

Spring AI 中的 AI 概念

本节介绍 Spring AI 使用的核心概念。建议你仔细阅读,以了解 Spring AI 实现背后的理念。

Model(模型)

人工智能模型(AI Model)是一种用于处理和生成信息的算法,通常模仿人类的认知功能。通过从大型数据集中学习模式和见解,这些模型可以做出预测、文本、图像或其他输出,从而增强各行业的各种应用。
有许多不同类型的 AI 模型,每种适用于特定的用例。虽然 ChatGPT 及其生成式 AI 能力通过文本输入和输出吸引了用户,但许多模型和公司提供多样化的输入和输出。在 ChatGPT 之前,许多人对文本转图像生成模型,如 Midjourney 和 Stable Diffusion,感到着迷。
下表根据输入和输出类型对几种模型进行了分类:
notion image
Spring AI 目前支持处理语言、图像和音频输入和输出的模型。上表中的最后一行接受文本作为输入并输出数字,通常被称为嵌入文本(Embedding Text),代表人工智能模型中使用的内部数据结构。Spring AI 支持嵌入,以实现更高级的用例。
GPT 等模型的与众不同之处在于其预训练特性,正如 GPT-Chat Generative Pre-trained Transformer 中的 “P” 所表示的那样。这种预训练功能将人工智能转变为一种通用开发工具,不需要广泛的机器学习或模型训练背景。

Prompt(提示)

提示(Prompt)是引导人工智能模型产生特定输出的语言输入的基础。对于熟悉 ChatGPT 的人来说,提示可能只是在对话框中输入并发送到 API 的文本。然而,它包含的内容远不止这些。在许多人工智能模型中,提示文本不仅仅是一个简单的字符串。
ChatGPT 的 API 在一个提示中包含多个文本输入,每个文本输入都被分配了一个角色。例如,system 角色会告诉模型如何操作,并为交互设置上下文。还有 user 角色,通常是来自用户的输入。
编写高效的提示既是一门艺术,也是一门科学。ChatGPT 专为人类对话而设计。这与使用类似 SQL 的东西来进行 “查询/对话” 完全不同。我们必须像与人对话一样与人工智能模型交流。
由于这种交互方式的重要性,“Prompt Engineering(提示工程)” 一词已成为一门独立的学科。提高提示有效性的技术层出不穷。在制作提示语方面投入时间,可以大大提高结果输出。
分享提示语已经成为一种共同的做法,学术界也在积极开展这方面的研究。最近的一篇研究论文发现,最有效的提示语之一是以 “深呼吸,一步一步来” 开头的。这应该能让你明白为什么语言如此重要。我们至今仍未完全掌握如何充分利用 ChatGPT 3.5 等早期迭代版本的技术,更遑论正在开发中的新一代模型了。

提示模板

设计优质提示词的关键在于构建请求的上下文框架,并将部分通用描述替换为用户输入的具体参数值。
该流程采用基于文本的传统模板引擎来实现提示词的创建与管理。为此,Spring AI 使用了开源库 StringTemplate 作为技术实现方案。
例如,一个简单的提示词模板如下:
在 Spring AI 中,提示词模板可类比 Spring MVC 架构中的 “View” 层。系统会提供一个模型对象(通常是 java.util.Map)来填充模板中的占位符,最终 “渲染” 生成的字符串将作为传递给 AI 模型的提示内容。
传递给 AI 模型的提示数据格式存在显著差异性。从最初简单的字符串形式,提示词已发展为包含多消息结构的复合形态 — 其中每条消息的字符串都对应着模型需要扮演的特定角色。

Embedding(嵌入)

嵌入是将文本、图像或视频转化为数值表示的技术,能够捕捉输入数据之间的关联性。
嵌入通过将文本、图像和视频转换为浮点数数组(称为向量)来工作。这些向量旨在捕捉文本、图像和视频的含义。嵌入数组的长度称为向量的维度。
通过计算两段文本向量表示之间的数值距离,应用程序即可判定原始对象在嵌入向量空间中的相似程度。
notion image
notion image
作为探索 AI 的 Java 开发者,你无需深究向量表示背后的复杂数学理论或具体实现细节。只需理解它们在 AI 系统中的角色和功能即可,特别是在将 AI 功能集成到应用程序时。
嵌入技术在检索增强生成(RAG)等实际应用中尤为重要。它们将数据表示为语义空间中的点 — 类似于欧氏几何的二维空间,但维度更高。就像欧氏几何中点的坐标决定其远近,语义空间中点的距离反映含义的相似性:话题相近的句子在多维空间中的位置更接近,如同图表上相邻的数据点。这种邻近性助力文本分类、语义搜索及产品推荐等任务,使 AI 能根据概念在这个扩展语义 “地图” 中的 “坐标” 来识别和归类相关内容。
你可以把这个语义空间想象成一个向量。

Token

令牌(Token)是 AI 模型运作的基础单元。输入时,模型将词语转换为令牌;输出时,再将令牌转换回词语。
在英语中,1 个 Token 大约对应 0.75 个单词。作为参考,莎士比亚全集约 90 万单词,对应约 120 万 Token。
notion image
更关键的是:Token 数量直接决定费用。在使用托管式 AI 模型时,系统会根据消耗的 Token 总量计费 — 无论是输入还是输出的 Token 都会被计入总用量。
此外,模型存在 Token 数量限制(即 “上下文窗口”),这会约束单次 API 调用中可处理的文本量。超出该阈值的文本内容将被直接截断,模型不会进行处理。
例如,ChatGPT3 的 Token 上限为 4K,而 GPT4 提供 8K、16K 和 32K 等不同规格。Anthropic 的 Claude AI 模型支持 100K Token,Meta 最新研究则实现了 100 万 Token 的突破性容量。
若要用 GPT4 概括莎士比亚全集,你需要设计软件工程策略来分割数据,确保内容不超出模型的上下文窗口限制。Spring AI 项目正为此类任务提供解决方案。

结构化输出

AI 模型的输出传统上以 java.lang.String 形式返回 — 即便要求生成 JSON 格式的答复。它可能是格式正确的 JSON,但本质仍是字符串而非 JSON 数据结构。要注意,在提示词中简单要求 “输出 JSON” 并不能百分百保证结果准确性。
这一复杂性催生了一个专门领域:既要设计能生成预期输出的提示词,又需将返回的原始字符串转换为可供应用程序集成的数据结构。
notion image
结构化输出 转换采用精心制作的提示,通常需要与模型进行多次交互才能实现所需的格式。

将你的数据与 API 接入 AI 模型

如何为 AI 模型提供其未经训练的信息?
需注意,GPT-3.5/4.0 的训练数据仅更新至 2021 年 9 月。因此,对于需要该日期之后知识的提问,模型会回答 “不知道”。有趣的是,该训练数据集大小约为 650GB。
现有三种技术可定制 AI 模型以整合你的数据:
  • 微调(Fine-Tuning):这项传统机器学习技术通过调整模型内部权重实现定制,但对 GPT 等大模型而言存在双重挑战 — 不仅需要专业机器学习知识,还因模型规模导致计算资源消耗极大。值得注意的是,部分模型可能根本不开放此功能。
  • 提示词填充(Prompt Stuffing):一种更实用的替代方案是将数据直接嵌入到提供给模型的提示词中。鉴于模型的 Token 限制,需要特定技术确保相关数据能适配上下文窗口。这种方法俗称 “提示词填充”。Spring AI 库能帮助你基于该技术(现多称为检索增强生成/RAG)实现解决方案。
notion image
  • 工具调用(Tool Calling):该技术支持注册工具(用户自定义服务),将大语言模型与外部系统 API 连接。Spring AI 大幅简化了实现 工具调用 所需的代码量。

检索增强生成(RAG)

检索增强生成(RAG)技术应运而生,专门解决将相关数据整合到提示词中以获取准确 AI 响应的难题。
该技术采用批处理编程模型:首先从文档中读取非结构化数据,经转换后写入向量数据库。本质上这是一个 ETL(抽取-转换-加载)流程,而向量数据库正是 RAG 技术中检索环节的核心组件。
将非结构化数据加载到向量数据库时,关键转换步骤之一是将原始文档分割成小块。这个分割过程包含两个重要环节:
  1. 在保留内容语义边界的前提下,将文档分割成若干部分。例如,对于包含段落和表格的文档,应避免在段落或表格中间分割文档。对于代码,应避免在方法实现的中间部分分割代码。
  1. 将初步分割后的文档块进一步细分,确保每个块的体积不超过 AI 模型 Token 限制的较小百分比(如15%-20%)。这种精细化处理既能适配模型上下文窗口,又最大限度保留语义连贯性。
RAG 的下一阶段是处理用户输入。当需要 AI 模型回答用户问题时,系统会将问题与所有 “相似” 的文档片段一起放入提示词中发送给模型。这正是使用向量数据库的原因 — 它极其擅长快速定位语义相似的内容。
notion image
  • ETL Pipeline:该管道协调从数据源提取数据、将其存储至结构化向量库的完整流程,确保数据在传递给 AI 模型时处于最佳检索格式。通过系统化的抽取-转换-加载操作,实现非结构化数据到高效可检索形式的精准转化。
  • ChatClient - RAG:该组件说明如何通过 QuestionAnswerAdvisor 在应用中启用检索增强生成功能,实现智能问答与上下文感知的响应生成。

 

工具调用

大语言模型(LLM)在训练完成后即固化,导致知识陈旧,且无法直接访问或修改外部数据。
工具调用机制(Tool Calling) 有效解决了这些局限。该功能允许你将自定义服务注册为工具,将大语言模型与外部系统 API 连接,使 LLM 能获取实时数据并委托这些系统执行数据处理操作。
Spring AI 极大简化了支持工具调用所需的编码工作,自动处理工具调用的对话交互。你只需将工具定义为带有 @Tool 注解的方法,并通过提示选项提供给模型即可调用。此外,单个提示中可定义和引用多个工具。
  1. 要让模型能够调用某个工具,需要在聊天请求中包含该工具的定义。每个工具定义包含名称、描述以及输入参数的 Schema。
  1. 当模型决定调用工具时,它会返回一个响应,其中包含工具名称和按照定义 Schema 建模的输入参数。
  1. 应用程序负责根据工具名称识别并执行对应工具,同时使用提供的输入参数进行操作。
  1. 工具调用的结果由应用程序负责处理。
  1. 应用程序将工具调用的结果返回给模型。
  1. 模型利用工具调用结果作为额外上下文生成最终响应。
有关如何在不同 AI 模型中使用此功能的详细信息,请参阅 工具调用 文档。

评估 AI 响应

有效评估 AI 系统对用户请求的响应输出,对于确保最终应用的准确性和实用性至关重要。目前已有多种新兴技术可利用预训练模型自身实现这一目标。
该评估流程需要分析生成内容是否契合用户意图及查询上下文,通过相关性、连贯性和事实准确性等指标来衡量 AI 响应的质量。
一种方法是将用户请求和 AI 模型响应同时提交给模型,询问该响应是否符合所提供的数据。
此外,利用向量数据库中存储的信息作为补充数据可以增强评估过程,有助于确定响应的相关性。
Spring AI 项目提供了 Evaluator API,目前支持基础策略来评估模型响应。更多信息请参阅 评估测试 文档。

总结

Spring AI 提供了一套全面的工具和抽象,极大地简化了在 Spring 应用中集成 AI 功能的过程。通过标准化的接口,开发者可以轻松地切换不同的 AI 服务提供商,同时保持应用程序代码的一致性。无论是构建简单的聊天机器人还是复杂的 AI 驱动系统,Spring AI 都提供了一条简捷的路径。
希望本文的介绍和实践代码能够帮助你快速上手 Spring AI,并在你的项目中发挥其强大的功能。如果你对 Spring AI 有更多问题或想法,欢迎在评论区交流。
Spring AI 中的 DocumentTransformer 与 RAG 深度解析流程条件表达式技术方案
Loading...