模型
AI 模型是用于处理和生成信息的算法,常常模拟人类的认知功能。通过从大型数据集中学习模式和洞见,这些模型能够进行预测、生成文本、图像或其他输出,进而在各行各业中提升应用效果。
AI 模型种类繁多,各自适用于特定的使用场景。虽然 ChatGPT 及其生成式 AI 能力因文本输入输出而受到广泛关注,但许多模型和公司提供的输入和输出形式是多样化的。在 ChatGPT 之前,许多人曾被 Midjourney 和 Stable Diffusion 等文本生成图像的模型所吸引。
下表根据输入和输出类型对几种模型进行了分类:
Spring AI 当前支持处理语言、图像和音频作为输入和输出的模型。前表中最后一行所示的模型,以文本为输入并以数字为输出,更常被称为文本嵌入,代表了 AI 模型中使用的内部数据结构。Spring AI 支持嵌入功能,以实现更高级的使用场景。
像 GPT 这样的模型之所以独特,是因为它们具有“预训练”特性,这也是 GPT 中 “P” 的含义——Chat Generative Pre-trained Transformer(聊天生成式预训练变换器)。这种预训练功能使 AI 成为一种通用的开发工具,用户无需深厚的机器学习或模型训练背景即可使用。
提示词
提示词是语言类输入的基础,引导 AI 模型生成特定的输出。对于熟悉 ChatGPT 的用户来说,提示词可能看起来只是输入框中的一段文本,被发送到 API,但它远不止如此。在许多 AI 模型中,提示词文本并不仅仅是一个简单的字符串。
ChatGPT 的 API 中,一个提示词由多个文本输入组成,每个文本输入都被分配了一个“角色”。例如,有一个 system 角色,用于告诉模型如何行为并设定交互的上下文;还有一个 user 角色,通常代表用户的输入。
编写有效的提示词既是一门艺术,也是一门科学。ChatGPT 是为人类对话而设计的,这与使用 SQL 等语言“提问”的方式有很大不同。人们必须以类似与他人交谈的方式与 AI 模型沟通。
正因为这种交互风格的重要性,“提示词工程(Prompt Engineering)”已成为一门独立的学科。目前已有一系列不断发展的技巧,用于提升提示词的效果。投入时间优化提示词,往往能显著改善生成结果。
分享提示词已经成为一种社区行为,同时学术界也在积极研究这一主题。为了说明编写有效提示词可能有多么反直觉(例如,相比 SQL 的明确性),一项最新研究发现,最有效的提示词之一是以“深呼吸一下,然后一步一步来”这样的语句开头。这足以说明语言的重要性。我们至今仍未完全理解如何最大化利用早期版本的 AI 技术(如 ChatGPT 3.5),更不用说正在开发中的新版本了。
提示词模板
编写有效的提示词涉及建立请求的上下文,并用用户特定的输入值替换请求中的部分内容。这个过程使用传统的基于文本的模板引擎来创建和管理提示词。Spring AI 使用开源库 StringTemplate 来实现这一功能。例如,考虑以下简单的提示词模板:
Tell me a {adjective} joke about {content}
在 Spring AI 中,提示词模板可以类比为 Spring MVC 架构中的 “View”。一个模型对象(通常是 java.util.Map)用于填充模板中的占位符。渲染后的字符串即成为提供给 AI 模型的提示词内容。提示词的具体数据格式存在较大差异。最初它们只是简单的字符串,如今已经演化为由多个消息组成的结构,每条消息中的字符串都代表模型的一个特定“角色”。
嵌入
嵌入(Embeddings)是文本、图像或视频的数值表示形式,用于捕捉输入之间的关系。
嵌入的原理是将文本、图像或视频转换为浮点数数组(称为向量)。这些向量旨在表达文本、图像或视频的语义含义。嵌入数组的长度被称为向量的“维度”。
通过计算两个文本向量表示之间的数值距离,应用程序可以判断生成这些嵌入向量的对象之间的相似度。对于探索 AI 的 Java 开发者来说,并不需要深入理解这些向量背后的复杂数学理论或具体实现。只需对嵌入在 AI 系统中的角色和作用有基本认识,特别是在将 AI 功能集成进应用程序时,就已经足够。
嵌入在诸如“检索增强生成”(RAG)等实际应用中尤为重要。它们能够将数据表示为语义空间中的点,类似于二维欧几里得空间,但维度更高。这意味着,就像欧几里得空间中两个点的距离可以反映它们的接近程度,在语义空间中,点之间的接近程度反映了它们语义上的相似性。关于相似主题的句子在这个多维空间中会彼此靠近,就像图上的点聚在一起一样。这种“接近性”有助于文本分类、语义搜索,甚至是产品推荐等任务,因为它使 AI 能够根据在语义空间中的“位置”识别和归类相关概念。
你可以将这个语义空间理解为一个向量。
Token
Token 是 AI 模型运作的基本单位。模型在接收输入时会将单词转换为 token,在生成输出时再将 token 转换回单词。在英文中,一个 token 大约相当于一个单词的 75%。例如,莎士比亚的全集大约有 90 万个单词,转换后大约是 120 万个 token。
更重要的是,Tokens 就等同于费用。在托管的 AI 模型中,收费是根据使用的 token 数量计算的,输入和输出的 token 都会计入总数。此外,模型对 token 数量有限制,限制了单次 API 调用可处理的文本量,这个限制通常称为“上下文窗口(context window)”。模型不会处理超过该限制的文本。例如,ChatGPT-3 的 token 限制是 4K,GPT-4 则提供多种选择,如 8K、16K 和 32K。Anthropic 的 Claude AI 模型支持 100K token 限制,Meta 最新研究的模型甚至达到了 1M token 限制。以 GPT-4 总结莎士比亚全集为例,你需要设计软件工程策略,将数据拆分成符合模型上下文窗口限制的部分。Spring AI 项目可以帮助你完成这项任务。
结构化输出
AI 模型的输出传统上是以 java.lang.String 形式返回的,即使你要求回复为 JSON 格式。虽然返回的字符串可能是正确的 JSON 格式,但它本质上仍然是一个字符串,而不是 JSON 数据结构。同时,在提示词中要求“输出 JSON”也并非百分之百准确。这种复杂性催生了一个专门领域,专注于设计提示词以产生预期输出,随后将得到的简单字符串转换成可供应用集成使用的数据结构。
结构化输出转换依赖于精心设计的提示词,通常需要与模型进行多轮交互,才能达到预期的格式效果。
将您的数据和API引入AI模型
如何让 AI 模型具备其未经过训练的信息?需要注意的是,GPT 3.5 和 GPT 4.0 的训练数据集只覆盖到 2021 年 9 月。因此,当问题涉及该日期之后的知识时,模型会表示不知道答案。有趣的是,这个数据集大约有 650GB。有三种技术可以用来定制 AI 模型,使其能够融合你的数据:
微调(Fine Tuning):这是传统的机器学习技术,通过调整模型并改变其内部权重来实现。但这对机器学习专家来说较为复杂,而且由于 GPT 这类模型体量庞大,微调非常消耗资源。此外,有些模型可能不支持微调。
提示词填充(Prompt Stuffing):一种更实用的方式是将你的数据嵌入到提供给模型的提示词中。考虑到模型的 token 限制,需要采用技术手段将相关数据有效地呈现在模型的上下文窗口内。这个方法俗称为“填充提示词”。Spring AI 库能帮助你基于“填充提示词”技术,也就是“检索增强生成”(Retrieval Augmented Generation,简称 RAG)来实现这一方案。
工具调用(Tool Calling):该技术允许注册工具(用户定义的服务),将大型语言模型与外部系统的 API 连接起来。Spring AI 大大简化了支持工具调用时所需编写的代码。
检索增强生成
一种称为“检索增强生成”(Retrieval Augmented Generation,简称 RAG)的技术应运而生,用于解决如何将相关数据有效融入提示词,从而让 AI 模型给出更准确回答的难题。该方法采用批处理式编程模型,工作流程是从文档中读取非结构化数据,进行转换,然后写入向量数据库。从宏观上看,这就是一个 ETL(提取 Extract、转换 Transform、加载 Load)管道。向量数据库在 RAG 技术中用于检索阶段。在将非结构化数据加载到向量数据库时,一个重要的转换步骤是将原始文档拆分成更小的片段。拆分原始文档的过程包含两个关键步骤:
- 在保持内容语义边界的前提下拆分文档。例如,对于包含段落和表格的文档,应避免在段落或表格中间拆分;对于代码,应避免在方法实现中间拆分。
- 进一步将拆分后的文档片段细分为大小仅占 AI 模型 token 限制的小比例的更小部分。
RAG 的下一阶段是处理用户输入。当用户提出问题时,问题内容及所有“相似”的文档片段会被一起放入发送给 AI 模型的提示词中。这就是使用向量数据库的原因,因为它非常擅长查找相似内容。
- ETL 管道负责协调从数据源提取数据、存储到结构化向量库的流程,确保数据在传递给 AI 模型进行检索时处于最佳格式。
- ChatClient - RAG 演示了如何使用 QuestionAnswerAdvisor,在你的应用中启用 RAG 功能。
工具调用
大型语言模型(LLM)在训练完成后即被冻结,导致其知识会变得过时,且无法访问或修改外部数据。工具调用(Tool Calling)机制正好解决了这些不足。它允许你将自定义服务注册为工具,将大型语言模型连接到外部系统的 API。这些系统可以为 LLM 提供实时数据,并代表其执行数据处理操作。Spring AI 大大简化了支持工具调用所需编写的代码。它为你处理工具调用的对话流程。你只需将工具方法用 @Tool 注解标记,并在提示词选项中提供该工具,使其对模型可用。此外,你还可以在单个提示词中定义并引用多个工具。
- 当我们希望让模型调用某个工具时,需要在聊天请求中包含该工具的定义。每个工具定义包括名称、描述以及输入参数的结构(schema)。
- 当模型决定调用工具时,会发送包含工具名称和按照定义的参数结构构造的输入参数的响应。
- 应用程序负责根据工具名称识别并执行对应的工具,并使用提供的输入参数。
- 工具调用的结果由应用程序进行处理。
- 应用程序将工具调用结果返回给模型。
- 模型利用工具调用结果作为额外上下文,生成最终回复。
评估人工智能响应
有效评估 AI 系统对用户请求的输出,对于确保最终应用的准确性和实用性非常重要。多种新兴技术使得可以利用预训练模型本身来完成这一评估任务。该评估过程包括分析生成的回答是否符合用户意图及查询上下文。评估指标通常涵盖相关性、一致性和事实正确性等方面,用以衡量 AI 生成回复的质量。一种方法是将用户请求和 AI 模型的回答一并呈现给模型,询问其回答是否与提供的信息相符。此外,利用存储在向量数据库中的信息作为补充数据,可以增强评估效果,有助于判断回复的相关性。