AI 概念

本节描述了 Spring AI 使用的核心概念。我们强烈建议您仔细阅读,以理解 Spring AI 实现背后的思想。

模型

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

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

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

Model types

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

像 GPT 这样的模型之所以与众不同,在于它们的预训练特性,GPT 中的 "P" 表示生成式预训练 Transformer (Generative Pre-trained Transformer)。这种预训练特性将 AI 转变为一种通用的开发工具,不再需要广泛的机器学习或模型训练背景。

提示词 (Prompts)

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

ChatGPT 的 API 在一个提示词内有多个文本输入,每个文本输入都被分配了一个角色。例如,有系统角色,它告诉模型如何表现并设置交互的上下文。还有用户角色,这通常是用户的输入。

精心设计有效的提示词既是一门艺术也是一门科学。ChatGPT 旨在进行人类对话。这与使用 SQL 这样的方式来“提问”完全不同。必须像与另一个人交谈一样与 AI 模型进行交流。

这种交互风格的重要性使得“提示工程 (Prompt Engineering)”成为了一门独立的学科。有一系列正在迅速发展的技术可以提高提示词的有效性。投入时间来设计一个提示词可以极大地改善产生的输出结果。

分享提示词已成为一种普遍做法,并且正在对该主题进行积极的学术研究。作为一个例子,说明创建有效提示词(例如,与 SQL 对比)可能多么违反直觉,最近的一篇研究论文发现,你能使用的最有效的提示词之一以短语“深呼吸,一步一步来 (Take a deep breath and work on this step by step.)”开头。这应该能让你明白语言为何如此重要。我们尚未完全理解如何最有效地利用这项技术的先前迭代版本,例如 ChatGPT 3.5,更不用说正在开发的新版本了。

提示模板 (Prompt Templates)

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

此过程使用传统的基于文本的模板引擎进行提示词创建和管理。Spring AI 使用 OSS 库 StringTemplate 来实现此目的。

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

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

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

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

嵌入 (Embeddings)

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

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

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

Embeddings

作为探索 AI 的 Java 开发者,无需理解这些向量表示背后复杂的数学理论或具体的实现细节。只需对它们在 AI 系统中的作用和功能有一个基本了解即可,尤其是在将 AI 功能集成到应用程序中时。

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

你可以将这个语义空间视为一个向量。

词元 (Tokens)

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

在英语中,一个词元大约相当于一个单词的 75%。作为参考,莎士比亚的全部作品总计约 900,000 个单词,转换为约 120 万个词元。

Tokens

也许更重要的是,词元 = 金钱。在使用托管 AI 模型时,你的费用取决于所使用的词元数量。输入和输出都会计入总词元数。

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

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

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

结构化输出

AI 模型的输出传统上是一个 java.lang.String,即使你要求以 JSON 格式回复。它可能是一个正确的 JSON 字符串,但它不是一个 JSON 数据结构。它只是一个字符串。此外,将“请求 JSON”作为提示词的一部分并不 100% 准确。

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

Structured Output Converter Architecture

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

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

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

请注意,GPT 3.5/4.0 的数据集仅截至 2021 年 9 月。因此,模型会回答说对于需要超出该日期知识的问题,它不知道答案。一个有趣的细节是,这个数据集大约有 650GB。

有三种技术可以定制 AI 模型以整合您的数据:

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

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

Prompt stuffing
  • 工具调用 (Tool Calling):此技术允许注册工具(用户定义的服务),将大型语言模型连接到外部系统的 API。Spring AI 极大地简化了您编写以支持工具调用所需的代码。

检索增强生成 (Retrieval Augmented Generation)

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

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

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

  1. 在保持内容语义边界的同时将文档分割成部分。例如,对于包含段落和表格的文档,应避免在段落或表格中间分割文档。对于代码,避免在方法的实现中间分割代码。

  2. 将文档的部分进一步分割成大小占 AI 模型词元限制很小百分比的部分。

RAG 的下一阶段是处理用户输入。当需要 AI 模型回答用户的提问时,该问题以及所有“相似”的文档片段都会被放入发送给 AI 模型的提示词中。这就是使用向量数据库的原因。它非常善于查找相似的内容。

Spring AI RAG
  • ETL 管道 提供了关于如何协调从数据源提取数据并将其存储在结构化向量存储中的更多信息,确保数据以最优格式存储,以便在将其传递给 AI 模型时进行检索。

  • ChatClient - RAG 解释了如何使用 QuestionAnswerAdvisor 在应用程序中启用 RAG 功能。

工具调用 (Tool Calling)

大型语言模型 (LLM) 在训练后是固定的,导致知识陈旧,并且无法访问或修改外部数据。

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

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

The main sequence of actions for tool calling
  1. 当我们要让模型可以使用某个工具时,我们将该工具的定义包含在聊天请求中。每个工具定义包括一个名称、一个描述以及输入参数的模式。

  2. 当模型决定调用某个工具时,它会发送一个响应,其中包含工具名称和根据定义的模式建模的输入参数。

  3. 应用程序负责使用工具名称识别并执行带有提供的输入参数的工具。

  4. 工具调用的结果由应用程序处理。

  5. 应用程序将工具调用结果发送回模型。

  6. 模型使用工具调用结果作为附加上下文生成最终响应。

请参阅工具调用文档,了解如何在不同的 AI 模型中使用此功能的更多信息。

评估 AI 响应

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

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

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

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

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