模型 (Models)
AI 模型是通过算法设计来处理和生成信息的系统,通常模拟人类认知功能。这些模型通过从海量数据中学习规律和知识,能够生成预测、文本、图像或其他输出,从而为各行业应用提供智能化增强。
人工智能模型种类繁多,每种模型都有其特定的适用场景。虽然 ChatGPT 及其生成式 AI 能力通过文本输入输出吸引了大量用户,但实际上许多模型和企业都支持多样化的输入输出形式。在 ChatGPT 之前,Midjourney 和 Stable Diffusion 等文生图模型就曾让无数人为之着迷。
下表根据输入输出类型对几种常见模型进行了分类:
Spring AI 当前支持的模型处理输入/输出的形式涵盖文本、图像和音频。前表中最后一行(接受文本输入并输出数字的模型)更常见的名称是文本嵌入模型,其输出代表 AI 模型内部使用的数据结构。Spring AI 通过嵌入支持实现了更高级的用例。
GPT 类模型的核心差异在于其预训练特性(名称中的 "P" 即代表 Pre-trained)。这种预训练机制将 AI 转化为通用开发者工具,使用者无需深厚的机器学习或模型训练背景即可调用。
提示词(Prompts)
提示词(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 集成了开源库 StringTemplate 作为技术解决方案。
例如,考虑以下简单的提示词模板:
Tell me a {adjective} joke about {content}."
在Spring AI中,提示词模板可类比Spring MVC架构中的"视图"。开发者通常提供一个java.util.Map类型的模型对象来填充模板中的占位符,最终"渲染"生成的字符串将作为提示词内容传递给AI模型。
需要注意的是,实际发送给模型的提示词数据格式存在显著差异。从最初简单的字符串形式,现已发展为包含多条消息的复合结构——其中每条消息的字符串都代表模型应扮演的特定角色。
嵌入(Embeddings)
嵌入(Embeddings)是将文本、图像或视频转化为数值表示的技术,这种表示能够捕捉输入内容之间的语义关系。
其工作原理是将文本、图像和视频转换为浮点数数组(称为向量 vector)。这些向量经过特殊设计,能够有效捕获原始内容的语义特征。嵌入数组的长度被称为向量的维度,通常维度越高,表征能力越强(如OpenAI的text-embedding-3-large模型支持3072维向量)。
通过计算两段文本向量表示之间的数值距离,应用程序可以判定原始内容之间的语义相似度。
对于正在探索AI领域的Java开发者而言,无需理解这些向量表示背后复杂的数学理论或具体实现细节。只要掌握它们在AI系统中的角色和功能就足够了,特别是在将AI功能集成到应用程序时。
嵌入技术(Embeddings)在检索增强生成(RAG)等实际应用中尤为重要。它们将数据表示为语义空间中的点——类似于欧几里得几何的二维空间,但维度更高。正如平面上的点根据坐标有远近之分,语义空间中点的邻近度反映了意义的相似性:谈论相似主题的句子会聚集在多维空间的相邻位置,就像图表上彼此靠近的数据点。这种邻近特性支撑了文本分类、语义搜索乃至产品推荐等任务,使AI能根据概念在这个扩展语义"地图"中的"位置"来识别和归类相关主题。
您可以将这个语义空间视为一个向量空间。
Tokens
Tokens(词元)是AI模型运作的基础单元。在输入时,模型将单词转换为词元;在输出时,再将词元转换回单词。
在英语中,一个词元大约相当于0.75个单词。例如,莎士比亚全集约90万单词,对应约120万词元。在中文文本处理中,1个汉字约等于1.3~2个Token(不同分词策略有差异),中文Token化依赖子词分割算法(如BPE)。
更关键的是,Token数量直接等同于费用。在使用托管型AI模型时,您的计费基于输入和输出的总Token消耗量。
此外,所有模型都存在Token限制(即"上下文窗口"),这会约束单次API调用能处理的文本总量。任何超出该限制的文本内容都会被模型自动截断处理。
例如,ChatGPT3的上下文窗口限制为4K Token,而GPT4提供了8K、16K和32K等不同规格。Anthropic的Claude AI模型支持高达100K Token,Meta的最新研究更是实现了1M Token的突破。
若要用GPT4总结莎士比亚全集,您需要通过软件工程策略将数据分割处理,使其适配模型的上下文窗口限制——而这正是Spring AI项目的核心助力方向。
结构化输出(Structured Output)
AI 模型的输出传统上以 java.lang.String 的形式返回,即使您要求回复为 JSON 格式。它可能是正确的 JSON,但并不是 JSON 数据结构——它仍然只是字符串。此外,在提示词中简单要求"生成 JSON"并不能保证 100% 的准确性。
这种复杂性催生了一个专门领域:通过精心设计提示词来获取预期输出,然后将返回的简单字符串转换为可供应用程序集成的可用数据结构。
构化输出转换需要精心设计的提示词,通常需要与模型进行多次交互才能实现预期的格式要求。
让数据与API接入AI模型
如何让AI模型掌握其未经训练的信息?
需知:GPT-3.5/4.0的训练数据仅覆盖至2021年9月,因此对于需要更新知识的提问,模型会直接表明无法回答(注:该训练数据集规模约为650GB)。
目前有三种技术可以让AI模型整合您的定制数据:
- 微调(Fine-Tuning)
- 传统机器学习技术,通过调整模型内部权重实现
- 对GPT等大模型实施难度大,需专业机器学习知识
- 计算资源消耗极高(如1750亿参数的GPT-3单次微调需数百GPU小时)
- 部分商用模型(如GPT-4)可能不开放此功能
- 提示词填充(Prompt Stuffing)
- 更实用的替代方案:将您的数据直接嵌入到提供给模型的提示词中
- 关键技术:由于模型的token限制,需要特殊技巧在上下文窗口内呈现相关数据
- 行业俗称:"提示词填充"(prompt stuffing)
- Spring AI支持:帮助您基于检索增强生成 (RAG) 技术实现解决方案
- 工具调用(Tool Calling)
- 核心机制:允许注册用户自定义服务,将大语言模型与外部系统API连接
- Spring AI优势:显著简化工具调用所需的代码实现
- 典型应用:
@Function
public WeatherData getWeather(@Parameter(description = "城市名称") String city) {
// 调用气象API返回实时数据
}
- 执行流程:模型识别需要调用的工具 → pring AI自动路由到对应服务 → 将API响应整合到最终回复
检索增强生成(Retrieval-Augmented Generation,RAG)
为解决将相关数据整合到提示中以获得准确AI模型响应的挑战,出现了一种称为检索增强生成(RAG)的技术。
该方法采用批处理式编程模型:
- 从文档中读取非结构化数据
- 对数据进行转换
- 将其写入向量数据库
本质上这是一个ETL(提取、转换、加载)流程。向量数据库用于RAG技术中的检索环节。
在将非结构化数据加载到向量数据库的过程中,最重要的转换之一是将原始文档分割成较小的片段。这一分割过程包含两个关键步骤:
- 语义边界保护:在分割文档时保持内容的语义完整性。例如,
对于含段落和表格的文档,避免在段落或表格中间分割;对于代码,避免在方法实现中途切断。 - 尺寸控制:将文档片段进一步分割,使每个片段的大小仅为AI模型token限制的一小部分
RAG技术的下一阶段是处理用户输入。当需要AI模型回答用户问题时,系统会将用户问题与所有"相似"的文档片段一起放入提示词中,发送给AI模型。这正是使用向量数据库的原因——它极其擅长查找语义相似的内容。
- ETL流程管道详细说明了如何协调从数据源提取数据,并将其存储到结构化向量数据库中的工作流,确保数据在传递给AI模型时处于最佳检索格式。
- ChatClient的RAG功能则通过QuestionAnswerAdvisor组件,指导开发者在应用中实现检索增强生成能力。
工具调用(Tool Calling)
大型语言模型(LLMs)在训练完成后即处于冻结状态,这导致其知识存在时效性局限,且无法直接访问或修改外部数据。
工具调用(Tool Calling)机制正是为解决这些缺陷而生。通过该机制,您可以将自有的服务注册为工具,从而将大语言模型与外部系统的API相连接。这些外部系统既能向LLM提供实时数据,也能代其执行数据处理操作。
Spring AI显著简化了支持工具调用所需的编码工作,自动为您处理工具调用的交互流程。您只需通过@Tool注解声明工具方法,并在提示选项中进行配置,即可让模型调用该功能。更值得一提的是,您可以在单次提示中同时定义并引用多个工具。
- 当我们需要让模型能够使用某个工具时,我们会在聊天请求中包含该工具的定义。每个工具定义由三部分组成:名称、描述和输入参数的格式规范。
- 当模型决定调用工具时,它会返回一个响应,其中包含工具名称和按照定义格式建模的输入参数。
- 应用程序负责根据工具名称识别对应工具,并使用提供的输入参数执行该工具调用。
- 应用程序处理工具调用的结果。
- 应用程序将工具调用结果发送回模型。
- 模型最终会利用工具返回的结果作为额外上下文,生成最终响应。
AI响应评估
有效评估AI系统对用户请求的响应输出,对确保最终应用的准确性和实用性至关重要。目前涌现的多种技术方案,能够直接利用预训练模型自身完成这一评估任务。
该评估流程的核心在于分析生成内容是否契合:
- 用户意图:回答是否精准匹配提问目标
- 查询上下文:内容是否与问题背景自洽
采用的衡量指标包括:
- 相关性:回答与问题的关联紧密度
- 连贯性:逻辑推理的流畅程度
事实准确性:信息与客观事实的一致性
典型评估方法
- 自指评估
- 将用户请求与AI响应同时提交给模型,要求其判断二者匹配度
- 知识增强评估
- 调用向量数据库中的存储信息作为补充依据,提升相关性判定精度
Spring AI支持
通过Evaluator API提供基础评估策略,当前支持:
EvaluationResult result = evaluator.evaluate(
userQuery,
aiResponse,
EvaluationCriteria.RELEVANCE | EvaluationCriteria.ACCURACY
);