0%

Spring AI 核心概念整理

翻译自官方文档:https://docs.spring.io/spring-ai/reference/concepts.html

AI 模型(AI Models)

AI 模型是旨在处理和生成信息的算法,通常模仿人类的认知功能。通过学习大规模数据集中的模式和洞察,这些模型可以进行预测、生成文本、图像或其他输出,从而增强各行各业的各种应用。

AI 模型有许多不同的类型,每种都适用于特定的用例。虽然 ChatGPT 及其生成式 AI 能力通过文本输入和输出吸引了大量用户,但许多模型和公司提供了多样化的输入和输出形式。在 ChatGPT 之前,许多人就对 Midjourney 和 Stable Diffusion 等文本生成图像模型着迷。

下表根据输入和输出类型对几种模型进行了分类:

输入 输出 示例
文本 文本 ChatGPT
文本 图像 Midjourney、Stable Diffusion
文本 音频 ElevenLabs
图像 文本 OCR、图像描述
文本 嵌入(数字) Embedding 模型

Spring AI 目前支持处理语言、图像和音频作为输入和输出的模型。上表中最后一行(接受文本作为输入并输出数字)通常被称为文本嵌入(Embedding),代表了 AI 模型内部使用的数据结构。Spring AI 支持嵌入功能,以实现更高级的用例。

GPT 等模型的独特之处在于其预训练特性——正如 GPT 中的 “P” 所表示的那样:Chat Generative Pre-trained Transformer(对话生成式预训练 Transformer)。这种预训练特性使 AI 转变为一种通用的开发者工具,无需深厚的机器学习或模型训练背景即可使用。


提示词(Prompts)

提示词(Prompt)是引导 AI 模型产生特定输出的基于语言的输入的基础。对于熟悉 ChatGPT 的用户来说,提示词可能看起来只是发送到 API 的对话框中输入的文本。然而,它远不止于此。在许多 AI 模型中,提示词的文本不仅仅是一个简单的字符串。

ChatGPT 的 API 在提示词中包含多个文本输入,每个文本输入都被分配了一个角色(Role)。例如:

  • system 角色:告诉模型如何行为,并设置交互的上下文。
  • user 角色:通常是来自用户的输入。

提示词工程(Prompt Engineering)

制作有效的提示词既是一门艺术,也是一门科学。ChatGPT 是为人类对话而设计的,这与使用 SQL 来”提问”截然不同。你必须像与另一个人交谈一样与 AI 模型沟通。

这种交互方式的重要性催生了“提示词工程(Prompt Engineering)”这一独立学科。有一系列新兴技术可以提高提示词的有效性。投入时间精心制作提示词可以显著改善最终输出。

分享提示词已成为一种社区实践,并且学术界也在积极研究这一课题。作为一个反直觉的例子(例如与 SQL 形成对比),最近的一篇研究论文发现,最有效的提示词之一以这样的短语开头:“深呼吸,一步一步来解决这个问题。” 这应该能让你明白语言为何如此重要。我们尚未完全理解如何最有效地使用这项技术的前几代版本(如 ChatGPT 3.5),更不用说正在开发的新版本了。

提示词模板(Prompt Templates)

创建有效的提示词涉及建立请求的上下文,并将请求的部分内容替换为用户特定的输入值。

这个过程使用传统的基于文本的模板引擎来创建和管理提示词。Spring AI 为此使用了开源库 StringTemplate

例如,考虑以下简单的提示词模板:

1
Tell me about {topic}

在 Spring AI 中,提示词模板可以类比为 Spring MVC 架构中的 “View”。一个模型对象(通常是 java.util.Map)被用来填充模板中的占位符。“渲染”后的字符串成为提供给 AI 模型的提示词内容。

发送到模型的提示词的具体数据格式存在相当大的差异。最初只是简单的字符串,提示词已经演变为包含多个消息,其中每个消息中的字符串代表模型的不同角色。


嵌入(Embeddings)

嵌入是文本、图像或视频的数值表示,用于捕获输入之间的关系。

嵌入通过将文本、图像和视频转换为浮点数数组(称为向量)来工作。这些向量旨在捕获文本、图像和视频的含义。嵌入数组的长度称为向量的维度

通过计算两段文本向量表示之间的数值距离,应用程序可以确定用于生成嵌入向量的对象之间的相似性。

作为一名探索 AI 的 Java 开发者,没有必要理解这些向量表示背后的复杂数学理论或具体实现。基本了解它们在 AI 系统中的角色和功能就足够了,尤其是当你将 AI 功能集成到应用程序中时。

嵌入的实际应用

嵌入在检索增强生成(RAG)模式等实际应用中尤为重要。它们使数据能够表示为语义空间中的点,这类似于欧几里得几何的二维空间,但维度更高。这意味着就像欧几里得几何中平面上的点可以根据其坐标有远有近一样,在语义空间中,点的接近程度反映了含义的相似性。关于相似主题的句子在这个多维空间中位置更近,就像图表上彼此靠近的点一样。这种邻近性有助于文本分类、语义搜索甚至产品推荐等任务,因为它允许 AI 根据其在这个扩展语义”景观”中的”位置”来辨别和分组相关概念。

你可以将这种语义空间想象为一个向量


Token

Token 是 AI 模型工作的基本构建块。在输入时,模型将单词转换为 Token;在输出时,模型将 Token 转换回单词。

在英语中,一个 Token 大致对应 0.75 个单词。作为参考,莎士比亚的全部作品总计约 90 万单词,转换为大约 120 万 Token

Token = 金钱

也许更重要的是:Token 就是金钱。在使用托管 AI 模型的场景中,你的费用取决于使用的 Token 数量。输入和输出都计入总 Token 数

此外,模型还受到 Token 限制,这限制了单次 API 调用中处理的文本量。这个阈值通常被称为“上下文窗口”(Context Window)。模型不会处理超出此限制的任何文本。

模型 Token 限制
ChatGPT 3 4K
GPT-4 8K / 16K / 32K
Anthropic Claude 100K
Meta 最新研究 1M

例如,要用 GPT-4 总结莎士比亚的全部作品,你需要设计软件工程策略来切分数据并在模型的上下文窗口限制内呈现数据。Spring AI 项目可以帮助你完成这项任务。


结构化输出(Structured Output)

AI 模型的输出传统上以 java.lang.String 的形式返回,即使你要求以 JSON 格式回复。它可能是一个正确的 JSON 字符串,但它不是一个 JSON 数据结构——它只是一个字符串。而且,在提示词中包含”请以 JSON 格式回复”并不能 100% 保证准确性。

这种复杂性催生了一个专门领域:创建提示词以产生预期输出,然后将结果简单字符串转换为可供应用程序集成使用的数据结构。

结构化输出转换采用精心制作的提示词,通常需要与模型进行多次交互才能实现所需的格式。


如何让 AI 模型获取未训练过的信息?

请注意,GPT 3.5/4.0 的数据集仅涵盖到 2021 年 9 月。因此,对于需要该日期之后知识的问题,模型会表示不知道答案。一个有趣的事实是:这个数据集大约有 650GB

有三种技术可以自定义 AI 模型以整合你的数据:

1. 微调(Fine Tuning)

这是一种传统的机器学习技术,涉及调整模型并更改其内部权重。然而,对于机器学习专家来说,这是一个具有挑战性的过程,而且对于像 GPT 这样规模的模型来说,资源消耗极大。此外,某些模型可能不提供此选项。

2. 提示词填充(Prompt Stuffing)

一种更实用的替代方案是将你的数据嵌入到提供给模型的提示词中。考虑到模型的 Token 限制,需要采用特定技术在模型的上下文窗口内呈现相关数据。这种方法被通俗地称为“填充提示词”(Stuffing the Prompt)。Spring AI 库可以帮助你基于”填充提示词”技术(也称为检索增强生成(RAG))实现解决方案。

3. 工具调用(Tool Calling)

这种技术允许注册工具(用户定义的服务),将大语言模型连接到外部系统的 API。Spring AI 极大地简化了你需要编写的支持工具调用的代码。


检索增强生成(RAG)

一种称为检索增强生成(Retrieval Augmented Generation,RAG)的技术应运而生,以解决将相关数据纳入提示词以获得准确 AI 模型响应的挑战。

该方法涉及一种批处理风格的编程模型,其中作业从文档中读取非结构化数据,对其进行转换,然后写入向量数据库。从高层次来看,这是一个 ETL(提取、转换和加载) 管道。向量数据库用于 RAG 技术的检索部分。

文档切分

作为将非结构化数据加载到向量数据库的一部分,最重要的转换之一是将原始文档拆分为更小的片段。将原始文档拆分为更小片段的过程有两个重要步骤:

  1. 在保留内容语义边界的同时拆分文档。 例如,对于包含段落和表格的文档,应避免在段落或表格中间拆分。对于代码,应避免在方法实现的中间拆分。
  2. 将文档片段进一步拆分为大小不超过 AI 模型 Token 限制一小部分的片段。

RAG 的下一个阶段:处理用户输入

当需要用 AI 模型回答用户的问题时,问题以及所有”相似”的文档片段都会被放入发送到 AI 模型的提示词中。这就是使用向量数据库的原因——它非常擅长查找相似内容

  • ETL 管道提供了关于编排从数据源提取数据并存储到结构化向量存储中的流程的更多信息,确保数据在传递给 AI 模型时处于最佳检索格式。
  • ChatClient - RAG 解释了如何使用 QuestionAnswerAdvisor 在应用程序中启用 RAG 功能。

工具调用(Tool Calling)

大语言模型(LLM)在训练后处于冻结状态,导致知识过时,并且无法访问或修改外部数据。

工具调用机制解决了这些缺陷。它允许你将自己的服务注册为工具,将大语言模型连接到外部系统的 API。这些系统可以为 LLM 提供实时数据并代表其执行数据处理操作。

Spring AI 极大地简化了你需要编写的支持工具调用的代码。它为你处理工具调用的对话流程。你可以将工具作为 @Tool 注解的方法提供,并在提示词选项中提供它,使其对模型可用。此外,你还可以在单个提示词中定义和引用多个工具。

工具调用流程

  1. 当我们想让模型可以使用某个工具时,我们将它的定义包含在聊天请求中。每个工具定义包括一个名称、描述和输入参数的模式(Schema)
  2. 当模型决定调用工具时,它会发送一个包含工具名称和按照定义模式建模的输入参数的响应。
  3. 应用程序负责使用工具名称来识别并使用提供的输入参数执行工具
  4. 工具调用的结果由应用程序处理。
  5. 应用程序将工具调用结果发送回模型
  6. 模型使用工具调用结果作为额外上下文生成最终响应。

有关如何在不同 AI 模型中使用此功能的更多信息,请参考工具调用文档


评估测试(Evaluation Testing)

有效地评估 AI 系统响应用户请求的输出,对于确保最终应用程序的准确性和实用性非常重要。几种新兴技术使使用预训练模型本身来实现此目的成为可能。

评估过程

评估过程涉及分析生成的响应是否与用户的意图和查询的上下文一致。使用相关性、连贯性和事实正确性等指标来衡量 AI 生成响应的质量。

一种方法是将用户的请求和 AI 模型的响应同时呈现给模型,询问响应是否与提供的数据一致。

此外,利用存储在向量数据库中的信息作为补充数据可以增强评估过程,有助于确定响应的相关性。

Spring AI 项目提供了一个 Evaluator API,目前提供了评估模型响应的基本策略。更多信息请参考评估测试文档