AI 概念

这一部分描述了Spring AI使用的核心概念。我们建议仔细阅读,以了解Spring AI实现背后的思想。

模型

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

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

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

输入 输出 示例

语言/代码/图像(多模态)

语言/代码

GPT4 - OpenAI,Google Gemini

语言/代码

语言/代码

GPT 3.5 - OpenAI-Azure OpenAI,Google Bard,Meta Llama

语言

图像

Dall-E - OpenAI + Azure,Deep AI

语言/图像

图像

Midjourney,Stable Diffusion,RunwayML

文本

数字

许多(也称为嵌入)

Spring AI最初的重点是处理语言输入并提供语言输出的模型,最初是OpenAI + Azure OpenAI。上表中的最后一行,接受文本作为输入并输出数字,更常被称为嵌入文本,代表了AI模型中使用的内部数据结构。Spring AI支持嵌入以支持更高级的用例。

像GPT这样的模型的独特之处在于它们的预训练性质,正如GPT中的“P”所示——Chat Generative Pre-trained Transformer。这种预训练功能将AI转变为一个通用的开发工具,不需要广泛的机器学习或模型训练背景。

提示

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

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

制作有效的提示既是一门艺术,也是一门科学。ChatGPT 被设计用于人类对话。这与使用 SQL “提问问题” 大不相同。你必须像与另一个人交谈一样与 AI 模型交流。

这种交互方式的重要性如此之大,以至于“提示工程”一词已经成为自己的学科。有许多技术可以提高提示的有效性。投入时间制作提示可以极大地改善最终的输出。

共享提示已经成为一种社群实践,并且正在积极进行关于这个主题的学术研究。作为创建有效提示的一个反直觉的例子(例如,与 SQL 相对比),一个 最近的研究论文 发现,你可以使用的最有效提示之一以“深呼吸,一步步来” 开始。这应该让你知道为什么语言如此重要。我们还没有完全理解如何最有效地利用先前版本的技术,如 ChatGPT 3.5,更不用说正在开发中的新版本了。

提示模板

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

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

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

告诉我一个关于 {content} 的 {adjective} 笑话。

在 Spring AI 中,提示模板类似于 Spring MVC 架构中的“视图”。一个模型对象,通常是 java.util.Map,被提供来填充模板中的占位符。生成的字符串成为提供给 AI 模型的提示的内容。

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

嵌入

嵌入将文本转换为数值数组或向量,使得AI模型能够处理和解释语言数据。从文本到数字再到文本的这种转换是AI与人类语言交互和理解的关键元素。作为一名探索人工智能的Java开发者,并不需要理解这些向量表示背后的复杂数学理论或具体实现。对于AI系统内部角色和功能的基本理解就足够了,特别是当您将AI功能集成到应用程序中时。

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

您可以将这个语义空间看作一个向量。

标记

标记是AI模型工作的基本单元。在输入时,模型将单词转换为标记。在输出时,它们将标记转换回单词。

在英语中,一个标记大致相当于一个单词的75%。作为参考,莎士比亚的全部作品总共约90万字,相当于约120万个标记。

也许更重要的是,标记=$

在托管AI模型的情况下,您的费用是由使用的标记数量决定的。输入和输出都会对总体标记数产生影响。

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

例如,ChatGPT3有4K标记的限制,而GPT4提供不同的选项,如8K、16K和32K。Anthropic的Claude AI模型具有100K标记的限制,而Meta的最新研究得到了一个100万标记的限制模型。

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

输出解析

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

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

输出解析使用精心设计的提示,通常需要与模型进行多次交互以实现所需的格式。

这一挑战促使OpenAI推出“OpenAI函数”作为从模型精确指定所需输出格式的手段。

将您的数据带给AI模型

您如何为AI模型提供其未经过训练的信息?

请注意,GPT 3.5/4.0数据集仅延伸到2021年9月。因此,模型会说它不知道需要超出该日期的知识的问题的答案。有趣的是,该数据集约为650GB。

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

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

  • 提示注入:一个更实用的选择涉及将您的数据嵌入到提供给模型的提示中。鉴于模型的令牌限制,需要技术来在模型的上下文窗口内呈现相关数据。这种方法俗称为“提示注入”。Spring AI库帮助您实现基于“提示注入”技术(又称检索增强生成(RAG))的解决方案。

  • 函数调用:此技术允许注册自定义的用户函数,连接大型语言模型与外部系统的API。Spring AI大大简化了您需要编写的支持函数调用的代码。

检索增强生成

一种称为检索增强生成(Retrieval Augmented Generation,RAG)的技术已经出现,旨在解决将相关数据整合到提示中以获取准确的AI模型响应的挑战。

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

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

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

  2. 将文档的部分进一步拆分为大小为AI模型标记限制的一小部分的部分。

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

在实现RAG时使用了几个概念。这些概念映射到Spring AI中的类:

  • DocumentReader:负责从数据源加载List<Document>的Java函数接口。常见的数据源包括PDF、Markdown和JSON。

  • Document:您的数据源的基于文本的表示,还包含描述内容的元数据。

  • DocumentTransformer:负责以各种方式处理数据(例如,将文档拆分成较小部分或向Document添加附加元数据)。

  • DocumentWriter:允许您将文档持久化到数据库(在AI堆栈中最常见的是向量数据库)。

  • Embedding:作为List<Double>的数据表示,由向量数据库用于计算用户查询与相关文档的“相似度”。

函数调用

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

函数调用 机制解决了这些缺点。它允许您注册自定义的用户函数,将大型语言模型连接到外部系统的 API。这些系统可以向LLMs提供实时数据,并代表其执行数据处理操作。

Spring AI极大地简化了您需要编写的代码,以支持函数调用。它为您代理了函数调用对话。您可以将您的函数提供为一个 @Bean,然后在提示选项中提供函数的bean名称以激活该函数。您还可以在单个提示中定义和引用多个函数。

评估AI响应

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

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

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

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

Spring AI项目目前提供了一些非常基本的示例,展示了如何在JUnit测试中包含用于评估响应的提示。