Spring AI之概述-AI概念

AI 概念

本节描述了 Spring AI 使用的核心概念。我们建议仔细阅读它,以了解 Spring AI 是如何实现的。

模型(Models)

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

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

下表根据模型的输入和输出类型对多个模型进行分类:

pringai0

图片解析:第一行主要阐述了“大型语言模型(LLM)”的功能和特点。这类模型的核心在于处理和生成“语言/代码”。在输入数据方面,LLM主要接收“语言/代码”作为其基础信息,但它的能力更为宽广,因为它可以“辅助采用图片、音频、视频作为多模态信息”进行输入。这意味着你可以向LLM提供这些不同类型的多媒体内容来丰富它理解任务的上下文,或者直接作为任务的一部分——例如,你可以给它一张图片,要求它用文字描述图片内容,LLM便会理解图像信息并生成相应的文字描述;同样,它也能理解音频或视频片段中的信息,并依据这些信息结合你用语言或代码下达的核心指令来完成任务。在处理完这些多样化的输入后,LLM主要的输出成果依然是“语言/代码”。然而,这种输出也可以“伴随音频形式的多模态输出”,这通常指的是其生成的文本结果可以通过文本转语音(TTS)技术转换成可以听到的声音,或者是模型生成的文本内容本身就是为音频应用(比如播客文稿、对话脚本等)而创作的,从而使得信息也能够通过听觉方式进行传递和接收。

第二行介绍了“图像生成模型 (Image Generation Model)”的运作方式。该模型主要接收“语言”(通常指文字描述,例如你告诉模型“画一只在沙滩上看书的猫”)和/或“图像”(即提供现有的图片作为参考或修改基础)作为输入数据类型。在处理这些输入信息后,图像生成模型会运用其专业能力,创造并输出全新的视觉内容,具体表现为“图像”或“视频”文件。因此,我们常说的“AI画画”、文本到图像(文生图)或图像到图像(图生图)的应用,正是这类模型功能的体现。

第三行展示了两种紧密相关但方向相反的AI模型功能,分别是“文本转语音模型 (Text-to-Voice Model)”和“语音转文本模型 (Voice-to-Text Model)”。当作为文本转语音模型时,它接收“语言”(即文字内容)作为输入数据类型,然后将这些文字信息转换并输出为“音频”(即声音或语音)。反过来,当作为语音转文本模型(也常被称为语音识别)时,它则接收“音频”(例如人的说话声)作为输入数据类型,并将其中的语音信息识别和转写成“语言”(即文字文本)作为输出结果。因此,图中的第三行实际上概括了人工智能在这两个方向上的应用:即将文字内容朗读出来,以及将语音内容记录成文字的核心流程。

第四行介绍的是“嵌入模型 (Embedding Model)”。这种模型非常灵活,能够接收多种不同类型的数据作为输入,具体包括“文本/图像/音频/视频 (Text/Image/Audio/Video)”。在接收这些多样化的输入后,嵌入模型的核心任务是将其转换并输出为“向量/嵌入 (Vector/Embedding)”。这些向量或嵌入是原始数据的一种数值表示形式,它们能够捕捉数据的核心语义特征,使得不同类型的数据可以在一个统一的向量空间中进行比较或处理,常用于相似性搜索、推荐系统、数据分类或作为其他AI模型的输入。

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

像 GPT 这样的模型的不同之处在于它们的预训练性质,如 GPT 中的“P”所示——聊天生成预训练转换器。这种预训练功能将 AI 转变为不需要广泛的机器学习或模型训练背景的通用开发人员工具。

提示(Prompts)

提示是基于语言的输入的基础,引导 AI 模型生成特定的输出。对于熟悉 ChatGPT 的人来说,提示可能看起来仅仅是在对话框中输入并发送到 API 的文本。然而,它包含的内容远不止于此。在许多 AI 模型中,提示的文本不仅仅是一个简单的字符串。

ChatGPT 的 API 在一个提示中有多个文本输入,每个文本输入都分配有一个角色。例如,有系统角色,它告诉模型如何行为并为交互设置上下文。还有用户角色,通常是来自用户的输入。

制作有效的提示既是一门艺术,也是一门科学。ChatGPT 是为人类对话而设计的。这与使用 SQL 之类的东西“提出问题”完全不同。一个人必须与 AI 模型进行交流,类似于与另一个人交谈。

正是这种交互方式的重要性,以至于 “Prompt Engineering” 这个术语已经成为一门独立的学科。有一系列新兴的技术可以提高提示的有效性。投入时间制作提示可以大大提高结果输出。

分享提示已成为一种公共实践,并且正在对这一主题进行积极的学术研究。作为创建有效提示(例如,与 SQL 形成对比)是多么违反直觉的一个例子, 最近的一篇研究论文发现(https://arxiv.org/abs/2205.11916),您可以使用的最有效的提示之一以短语开头,“深呼吸并逐步完成这项工作。” 这应该可以告诉你为什么语言如此重要。我们还不完全了解如何最有效地利用这项技术的先前迭代,例如 ChatGPT 3.5,更不用说正在开发的新版本了。

设计有效的 AI 提示语这件事,不像写 SQL 查询语句那样,有一套非常清晰、逻辑化、符合我们对计算机指令直觉的成熟方法。SQL 那种“你怎么想,就怎么精确地写,然后得到精确结果”的经验和直觉,在 AI 提示语的领域可能并不完全适用。AI 提示语的有效性有时会以一种出乎我们常规逻辑预料的方式展现出来,这正是它的“反直觉”之处,也是它与 SQL 这类传统的、结构化的计算机指令语言形成鲜明对比的地方。

提示模板

创建有效的提示包括建立请求的上下文,并将请求的各个部分替换为特定于用户输入的值。

此过程使用传统的基于文本的模板引擎进行提示创建和管理。Spring AI 为此使用了 OSS 库 StringTemplate(https://www.stringtemplate.org/)。

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

me a {adjective} joke about {content}.
1
Tell me a {adjective} joke about {content}.

在 Spring AI 中,提示模板可以比作 Spring MVC 架构中的“视图”。提供模型对象(通常是 java.util.Map)来填充模板中的占位符。“rendered” 字符串成为提供给 AI 模型的提示的内容。

发送到模型的提示的特定数据格式存在相当大的变化。提示最初从简单字符串开始,现在已经发展到包含多条消息,其中每条消息中的每个字符串代表模型的不同角色。

嵌入(Embeddings)

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

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

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

pring-ai-embedding

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

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

您可以将此语义空间视为一个向量。

想让电脑理解我们人类世界里的东西,比如一句话、一张图片,甚至一段视频。电脑本身只认识数字,不认识我们说的“猫”、“狗”或者画出来的猫和狗。“嵌入”就像一个超级翻译官 👨‍💻。这个翻译官不把中文翻译成英文,而是把我们世界里的各种信息(文字、图片、视频)“翻译”成电脑能懂的一串数字。这一串数字,我们就叫它向量 (Vector)。这是“嵌入”最神奇的地方!一旦我们把不同的东西都翻译成了这种数字串(向量),我们就可以通过计算这些数字串之间的“距离”来看它们有多相似。

语义空间:我们平时看的地图是二维的(有长度和宽度),你在地图上标一个点,代表一个地方。两个点离得近,说明这两个地方在地理上也近。
“语义空间”也是一个“地图”,但它可能有很多很多维度(不只是二维或三维)。在这个地图上,每一个被“嵌入”翻译过的信息(比如一个词、一句话、一张图片)都会变成一个点。
关键在于:在这个语义空间的“地图”上,意思相近的东西,它们对应的点就会离得比较近;意思差别大的,点就离得远。比如,“国王”这个词的点,可能会离“女王”这个词的点比较近,但会离“香蕉”这个词的点比较远。

检索增强生成 (RAG):这是一个很流行的AI技术模式。简单说,就是当AI(比如一个聊天机器人)要回答你的问题时,它先用“嵌入”技术把你提问的内容,和它知识库里的一大堆资料都变成数字串。然后,它在知识库里找到和你提问的数字串最“近”(也就是最相关)的几段资料,再结合这些资料来生成答案。这样AI就能给出更准确、更有依据的回答了。

令牌(Tokens)

令牌是 AI 模型工作原理的构建块。在输入时,模型将单词转换为令牌。在输出时,它们将令牌转换回单词。

在英语中,一个词元大约相当于 0.75 个单词。作为参考,莎士比亚全集总共大约 900,000 个单词,翻译成大约 120 万个词元。

pring-ai-concepts-token

也许更重要的是,令牌 = 货币。在托管 AI 模型的上下文中,您的费用由使用的令牌数量决定。输入和输出都会影响总令牌计数。

此外,模型还受令牌限制的约束,这些限制限制了在单个 API 调用中处理的文本量。此阈值通常称为“上下文窗口”。模型不会处理任何超过此限制的文本。

例如,ChatGPT3 有 4K 代币限制,而 GPT4 提供不同的选项,例如 8K、16K 和 32K。Anthropic 的 Claude AI 模型具有 100K 代币限制,而 Meta 最近的研究产生了 1M 代币限制模型。

要使用 GPT4 总结莎士比亚的收集作品,您需要设计软件工程策略来切碎数据并在模型的上下文窗口限制内呈现数据。Spring AI 项目可以帮助您完成此任务。

结构化输出

AI 模型的输出传统上以 java.lang.String 的形式到达,即使您要求回复为 JSON。它可能是正确的 JSON,但它不是 JSON 数据结构。它只是一个字符串。此外,在提示中请求“for JSON”并非 100% 准确。

这种复杂性导致了一个专业领域的出现,该领域涉及创建提示以产生预期的输出,然后将生成的简单字符串转换为可用于应用程序集成的数据结构。

tructured-output-architectur

结构化输出转换(https://docs.spring.io/spring-ai/reference/api/structured-output-converter.html#_structuredoutputconverter)采用精心设计的提示,通常需要与模型进行多次交互才能获得所需的格式。

将您的数据和 API 引入 AI 模型

如何为 AI 模型配备尚未训练的信息?

请注意,GPT 3.5/4.0 数据集仅延长至 2021 年 9 月。因此,该模型表示它不知道需要该日期之后知识的问题的答案。一个有趣的琐事是,这个数据集大约有 650GB。

有三种技术可用于自定义 AI 模型以合并您的数据:

  • 微调 :这种传统的机器学习技术涉及定制模型和更改其内部权重。然而,对于机器学习专家来说,这是一个具有挑战性的过程,并且由于 GPT 等模型的大小,它非常耗费资源。此外,某些型号可能不提供此选项。
  • Prompt Stuffing:一种更实用的替代方案涉及将数据嵌入到提供给模型的提示中。给定模型的 token 限制,需要技术在模型的上下文窗口中呈现相关数据。这种方法俗称 “填充提示”。Spring AI 库可帮助您实现基于“填充提示”技术的解决方案,也称为检索增强生成 (RAG)(https://docs.spring.io/spring-ai/reference/concepts.html#concept-rag)。

pring-ai-prompt-stuffin

检索增强一代

一种称为检索增强生成 (RAG) 的技术已经出现,用于解决将相关数据纳入提示以实现准确 AI 模型响应的挑战。

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

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

  • 将文档拆分为多个部分,同时保留内容的语义边界。例如,对于包含段落和表格的文档,应避免在段落或表格的中间拆分文档。对于代码,请避免在方法实现的中间拆分代码。
  • 将文档的各个部分进一步拆分为大小占 AI 模型令牌限制的一小部分。

RAG 的下一阶段是处理用户输入。当 AI 模型要回答用户的问题时,问题和所有“相似”文档片段都会被放入发送到 AI 模型的提示中。这就是使用矢量数据库的原因。它非常擅长寻找相似的内容。

pring-ai-ra

工具调用

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

工具调用(https://docs.spring.io/spring-ai/reference/api/tools.html)机制解决了这些缺点。它允许您将自己的服务注册为工具,以将大型语言模型连接到外部系统的 API。这些系统可以为 LLM 提供实时数据,并代表它们执行数据处理作。

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

ool-calling-0

  1. 当我们想要使工具可供模型使用时,我们会在聊天请求中包含其定义。每个工具定义都包含名称、描述和输入参数的架构。
  2. 当模型决定调用工具时,它会发送一个响应,其中包含工具名称和输入参数,这些参数在定义的架构之后建模。
  3. 应用程序负责使用工具名称来识别和执行具有提供的输入参数的工具。
  4. 工具调用的结果由应用程序处理。
  5. 应用程序将工具调用结果发送回模型。
  6. 该模型使用 tool call result 作为附加上下文生成最终响应。

有关如何将此功能与不同 AI 模型一起使用的更多信息,请遵循工具调用(https://docs.spring.io/spring-ai/reference/api/tools.html)文档。

评估 AI 响应

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

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

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

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

Spring AI 项目提供了一个 Evaluator API,它目前可以访问评估模型响应的基本策略。有关详细信息,请遵循评估测试(https://docs.spring.io/spring-ai/reference/api/testing.html)文档。