生成 AI 解决方案的关键概念和注意事项
大型语言模型(LLM)是惊人的,但它们有限制。 作为开发人员,你需要了解这些限制、LLM 能够“开箱即用” 的功能,以及如何对其进行修改,以获得你所构建的生成式 AI 解决方案的最佳结果。 本文介绍了 LLM 的若干挑战和限制因素。 它解释了克服挑战并控制内容生成过程的常见方法,而不管构建在应用程序中的生成 AI 功能类型如何。
使用 LLM 时的工程挑战
以下列表总结了使用 LLM 时要注意的最重大挑战或限制:
知识截止:由于 LLM 训练成本高,LLM 的知识主体仅限于在某个时间点接受训练的内容。 没有任何插件或其他适配措施,LLM 无法访问实时信息,也无法访问私人数据。
幻觉:LLM 使用统计概率和一点随机性来生成信息。 已建立了机制,以确保生成的响应与提问者的意图和 LLM 的训练信息保持一致,但 LLM 仍可能生成不准确的答复。
透明度:此外,由于 LLM 的训练方式,它不再能够获得所训练的基础知识。 即使它做到了,也不能保证信息是真实和有根据的。 此外,没有验证步骤来确保生成的响应准确。
没有特定领域的知识:与知识截止类似,如果你有私密信息(如内部专用的公司文档),则 LLM 未就此信息进行培训。 它没有关于具体领域数据的知识。
可以做些什么来缓解 LLM 可能存在的挑战或问题,并获得最佳结果来帮助用户和组织? 首先,了解如何补充 LLM 获取数据的地方。
LLM 从哪里获取信息
从 LLM 获得最佳结果的一个好起点是,了解 LLM 从何处或如何获取其信息。 以下类别表示 LLM 如何与各种信息源进行交互以生成响应的不同方法。
检索关闭生成 (ROG):传统 LLM 使用此模型。 该模型仅基于其训练的知识生成响应,而无需在生成过程中访问或检索任何外部信息。 模型的知识是静态的,并且仅限于其训练数据中截止日期前包含的内容。 除了创造性的写作,它还可以回答有关互联网上随时可用的信息的问题。
检索扩充生成(RAG):将 LLM 的生成功能与从外部数据库或文档实时检索信息的功能相结合。 该模型查询外部源以查找相关信息。 然后,它使用信息来形成其响应。 这种方法允许模型提供比单独使用预训练知识更准确和最新的信息。 用例包括事实检查、基于实时数据回答问题,或基于专用域特定数据回答问题。
以检索为中心的生成(RCG):更加注重外部检索的内容,通常围绕从外部源提取的信息构建响应。 模型可以直接将检索到的大量文本段合并到其输出中,编辑或批注它们以适应用户的查询。 这种方法可以被视为一种结合检索和生成两种方法的混合方法,在此过程中,平衡可能更多地倾向于利用检索到的信息,而不是模型自身的生成能力。 用例包括汇总较长文档、提供跨多个相似文档的比较和主题探索的研究支持,以及将来自不同材料来源的内容整理为组合输出。
ROG 的一个很好的示例是 ChatGPT。 相比之下,Copilot(通过必应)通过使用来自新闻源的外部来源(以及提供指向这些来源的链接)来扩展 LLM。
首先,RAG 和 RCG 看起来类似,因为两者都涉及将外部信息集成到语言生成过程中。 但是,它们在生成过程中的优先级和使用检索到的信息的方式有所不同。
在 RAG 系统中,外部数据检索用于 增强 预先训练的语言模型的生成功能。 检索到的信息提供了模型用于通知其响应的更多上下文或特定数据。 在 RAG 系统中,语言模型的生成方面仍然是响应的核心。 检索的数据充当支持元素,以提高准确性或深度。
RCG 系统更强调检索到的信息本身。 在 RCG 系统中,检索的数据通常是响应的核心,而生成式模型的角色主要是优化、设置格式或稍微增强检索的文本。 当信息的准确性和直接相关性至关重要时,尤其使用此方法,并且需要较少的创造性合成或推断。
在关于存储文档的矢量化嵌入与优化 LLM 的文章中,讨论了支持 RAG 和 RCG 的外部数据检索机制,这是基于 LLM 的初始训练补充 LLM 可用知识的两种流行方法。
了解检索模型之间的区别有助于为特定应用程序选择合适的方法。 它有助于平衡对源材料创造性合成与准确性和保真度的需求。
影响推理工作原理的因素
由于你可能熟悉 ChatGPT 的基于 Web 的用户界面,因此了解如何回答问题有助于了解在自己的应用程序中生成生成 AI 功能时至关重要的概念。
当用户与 ChatGPT 聊天时,用户界面设计给你一种长时间运行的聊天会话的错觉,该会话会在你和 LLM 之间进行多次来回交换时保持状态。 实际上,对于给定的聊天会话,所有提示和所有 LLM 响应(也称为补全)都会随着每个新提示一起被发送。 随着你们的对话越来越深入,你向 LLM 发送越来越多的文本来处理。 对于每个新提示,你都会发送所有以前的提示和完成。 ChatGPT 在撰写对您当前提示的响应时,会使用整个聊天会话的上下文,而不仅仅是只考虑当前提示。 整个聊天会话称为 上下文窗口。
上下文窗口的长度限制因所使用的 ChatGPT 版本而异。 当 ChatGPT 撰写对最新提示的响应时,将忽略超出上下文窗口长度限制的聊天对话的任何部分。
长对话起初似乎是个好主意,但长上下文窗口可能会影响处理提示和撰写完成所需的计算量。 上下文窗口的大小会影响响应的延迟以及 OpenAI 处理请求的成本。
ChatGPT 的上下文窗口限制是什么? 也就是说,ChatGPT 可以处理多少个词?
上下文窗口限制取决于你正在使用的 LLM 模型、版本和版次。 此外,上下文长度以令牌而不是字词来度量。 令牌是模型可以理解和生成的最小文本单位。 这些单位可以是单词、部分字词(如音节或词干),甚至是单个字符。 令牌是自然语言处理的核心(NLP)。
令牌的使用会影响开发人员的两个重要注意事项:
- 最大上下文窗口限制
- 每次提示和完成的价格
什么是令牌化?
标记化 是将文本转换为令牌的过程。 这是为使用 LLM 进行训练或推理(即根据提示生成完成内容)的数据准备过程中的关键步骤。 该过程涉及几个步骤,包括将复杂文本分解为可管理的部分(令牌),然后模型可以处理这些内容。 此过程可能很简单,例如按空格和标点符号拆分文本,或者更复杂的过程,涉及处理不同语言的复杂算法、词法(单词的结构)和语法(单词排列)。 LLM 研究人员和开发人员根据他们正在尝试实现的内容来决定令牌化的方法。
OpenAI tokenizer 页详细介绍了词汇切分。 该页面甚至有一个计算器,用于说明句子或段落如何分解为标记。
正如 OpenAI Tokenizer 页面底部的注释所指出的,在典型的英语文本中,一个标记相当于大约四个字符。 平均而言,100 个令牌大约等于 75 个单词,即每个令牌大约有四分之三个单词。
OpenAI Tokenizer 页还介绍了 tiktoken,这是 Python 和 JavaScript 的包,可用于以编程方式估计向 OpenAI API 发送特定提示所需的令牌数。
令牌使用情况会影响计费
每个 Azure OpenAI API 都有不同的计费方法。 使用聊天完成 API 处理和生成文本时,会根据你提交的提示令牌数量以及生成的结果令牌数量(完成情况)进行计费。
每个 LLM 模型(例如 GPT-3.5、GPT-3.5 Turbo 或 GPT-4)通常有不同的价格,这反映了处理和生成令牌所需的计算量。 很多时候,价格显示为“每1000个令牌的价格”或“每100万个令牌的价格”。
此定价模型对如何设计用户交互以及添加的预处理和后期处理量具有显著影响。
系统提示与用户提示
到目前为止,讨论只集中在用户提示。 用户提示是构成用户与 ChatGPT 之间的交换的提示类型。
OpenAI 引入了 系统提示(也称为 自定义指令)。 系统提示是一组由你定义并添加到所有聊天对话中的全面说明。 可以将其视为一组元指令,希望 LLM 在每次开始新的聊天会话时始终遵循这些指令。 例如,可以将系统提示设置为“始终以海库诗意的形式做出响应”。从那以后,ChatGPT 的每个新提示都会生成包含答案的 haiku。
虽然“以俳句形式作答”不是一个有用的例子,但它确实说明了可以通过修改提示本身来影响 LLM 对提示的完成。
为何要修改用户的提示? 如果要为专业受众构建生成 AI 功能或应用程序(可能包括公司员工、客户和合作伙伴),则无疑希望添加安全措施来限制其可以回答的主题或域的范围。
但是,修改用户提示只是改善用户文本生成体验的一种方法。
改善 ChatGPT 中用户的文本生成体验的方法
为了改进文本生成结果,开发人员仅限于改进提示,并且有许多提示工程技术可以帮助。 但是,如果要构建自己的生成 AI 应用程序,可通过多种方式改进用户的文本生成体验,并且可能需要尝试实现所有这些应用:
- 以编程方式修改用户提示。
- 实现推理管道。
- Retrieval-Augmented世代(在其他文章中讨论)。
- 优化(其他文章中已讨论)。
以编程方式修改用户提示
若要向用户对话添加系统提示,请不要使用特殊 API。 只需根据需要在提示中附加指令。
但是,可以使用一些方法来改进用户提示:
- 上下文启动:创建系统提示,明确在特定域中设定会话的上下文。 此方法涉及在每个交互开始时提供简短说明或一组说明。 这些说明指导 AI 保留在问题域中。
- 基于示例的指导:在初始提示中,包括与域相关的问题和答案类型的示例。 此方法可帮助 AI 了解预期响应类型。
可以使用任何提示工程技术。 如果可以通过编程方式完成此操作,可以代表用户改进用户提示。
需要注意的是,此方法的提示内容越长,每次调用 LLM 的成本就越高。 即便如此,此方法可能是本文介绍的开销最低的方法。
实现推理管道
除了以编程方式修改用户的提示之外,下一步是创建整个推理管道。
推理管道是一个端到端的过程,在使用原始输入(如文本或图像)执行主要提示(预处理)之前对其进行“清理”,或者在显示之前检查完成情况以确保其满足用户的需求(后处理)。
预处理可能涉及关键字检查、相关性评分或转换查询,以更好地适应预期的域语言。 例如,可以分析用户提交的初始提示。 首先询问 LLM,提示是否有意义,是否在你愿意接受的范围内,是否基于错误的前提,或者是否需要重写以避免某些偏见。 如果 LLM 分析提示后发现问题,你可能需要采取更进一步的措施。 可以请 LLM 修改提示,以可能改进答案。
后处理可能涉及验证答案与域的相关性和适当性。 它可能包括删除或标记不符合域要求的答案。 例如,你可能想要检查 LLM 提供的完成情况,以确保它满足质量和安全要求。 你可以要求 LLM 评估答案,看看它是否确实满足你要求它遵守的要求。 如果没有出现预期结果,则可以要求 LLM 修改结果。 重复这些步骤,直到获得令人满意的结果。
需要注意添加预处理步骤:每次在推理管道中添加对 LLM 的调用时,都会增加总体延迟(响应时间)以及每次与用户交互的成本。 作为一名经验丰富的软件开发人员,你可能已经了解了这些影响软件系统预算、性能和有效性的权衡。
有关构建推理管道的具体步骤的信息,请参阅 构建高级检索增强生成系统。
影响完成的其他因素
除了以编程方式修改提示、创建推理管道和其他技术外,更多的详细信息在通过检索增强生成和微调来扩充大型语言模型中讨论。 此外,还可以在调用 Azure OpenAI API 时修改参数。
若要查看可能影响完成各个方面的必需参数和可选参数,请参阅聊天终结点文档。 如果使用 SDK,请参阅所用语言的 SDK 文档。 可以在 Playground 中试验参数。
Temperature
:控制模型生成的输出的随机性。 从零开始,模型会变得确定性,始终从其训练数据中选择最有可能的下一个标记。 当温度为 1 时,模型在选择高概率标记和引入输出随机性之间达到平衡。Max Tokens
:控制响应的最大长度。 设置较高或较低的限制可能会影响所生成内容的详细信息和范围。Top P
(核采样):与Temperature
一起使用来控制响应的随机性。Top P
将 AI 限制为在生成每个标记时仅考虑概率质量的最高百分比(P
)。 较低的值会导致文本更加集中且可预测。 较高的值允许更多的多样性。Frequency Penalty
:降低模型重复相同行或短语的可能性。 增加此值有助于避免生成的文本中的冗余。Presence Penalty
:鼓励模型在完成时引入新的概念和术语。Presence Penalty
可用于生成更加多样化和创造性的输出。Stop Sequences
:可以指定一个或多个序列来指示 API 停止生成更多令牌。Store Sequences
有助于控制输出的结构,例如在句子或段落末尾结束完成。Logit Bias
:允许修改指定令牌在完成中出现的可能性。Logit Bias
可用于指导特定方向完成或禁止显示特定内容。
Microsoft OpenAI 安全措施
除了让 LLM 的响应限于特定主题或领域,你也可能关心用户向 LLM 提问的问题类型。 请务必考虑它生成的答案类型。
首先,API 调用 Microsoft OpenAI Services 会自动筛选 API 查找的潜在冒犯性内容,并在许多筛选类别中将此报告回给你。
可以直接使用 OpenAI 审查 API 来检查任何内容是否存在潜在的有害内容。
然后,可以使用 Azure AI 内容安全来帮助进行文本审查、图像审查、越狱风险检测和受保护的材料检测。 这会将门户设置、配置和报告体验与可添加到应用程序的代码相结合,以识别有害内容。
应用程序设计的最终注意事项
了解令牌化、定价、上下文窗口和实现编程改进,以增强用户的文本生成体验会影响你设计生成 AI 系统的方式。
下面是本文要考虑的事项和其他要点的简短列表,这些内容可能会影响应用程序设计决策:
- 根据成本注意事项评估使用最新 AI 模型的必要性。 成本较低的模型可能足以满足应用程序的需求。 平衡性能与预算限制。
- 请考虑优化上下文窗口长度来管理成本,而不会影响用户体验。 剪裁聊天中不必要的部分可能会降低处理费用,同时保持质量交互。
- 评估输入和输出的标记化和粒度如何影响性能。 了解所选 LLM 如何处理令牌化,有助于优化 API 调用的效率,降低成本并提高响应时间。
如果想要立即开始尝试构建生成式 AI 解决方案,建议查看使用你自己的 Python 数据示例开始聊天。 本教程还可用于 .NET、Java和 JavaScript。